You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by "Ralf S. Engelschall" <rs...@engelschall.com> on 1998/04/17 17:49:23 UTC
[PATCH] sections
<IfDefine> Sections
===================
This patch adds a useful <IfDefine>...</IfDefine> section to the core module
very similar to the existing <IfModule>...<IfModule> sections. The intent is
to provide _LOGICAL_ conditions based on arbitrary defined parameters, because
the module-existance-based <IfModule> sometimes don't help. For instance when
you want to conditionally load DSO based modules you cannot use <IfModule>,
because first this condition is not dependend of any module existance and
second conditions of loading modules cannot depend on their existance.
Although for conditional LoadModule this <IfDefine> feature is the only way,
it can be also very useful for any types of other logical conditions.
Example:
$ httpd ... -DReverseProxy ....
# httpd.conf
<IfDefine ReverseProxy>
LoadModule rewrite_module libexec/mod_rewrite.so
LoadModule proxy_module libexec/libproxy.so
</IfDefine>
<IfDefine !ReverseProxy>
<IfDefine PerlEngine>
LoadModule perl_module libexec/libperl.so
</IfDefine>
....
</IfDefine>
Because it's an additional feature, I know, it is too late for 1.3.0. But for
1.3.1 this could be a useful addition. The below patch includes code,
documentation and even CHANGES file additions.
Greetings,
Ralf S. Engelschall
rse@engelschall.com
www.engelschall.com
Index: src/CHANGES
===================================================================
RCS file: /e/apache/REPOS/apache-1.3/src/CHANGES,v
retrieving revision 1.770
diff -u -r1.770 CHANGES
--- CHANGES 1998/04/16 17:30:46 1.770
+++ CHANGES 1998/04/17 15:17:23
@@ -1,3 +1,17 @@
+Changes with Apache 1.3.1
+
+ :
+
+ *) Add <IfDefine>..</IfDefine> sections to the core module (with same spirit
+ as <IfModule>..</IfModule> sections) which can be used to skip or process
+ contained commands dependend of ``-D PARAMETER'' options on the command
+ line. This can be used to achieve logical conditions like <IfDefine
+ ReverseProxy> instead of physically ones (e.g. <IfModule mod_proxy.c>)
+ and thus especially can be used for conditionally loading DSO-based
+ modules via LoadModule, etc. [Ralf S. Engelschall]
+
+ :
+
Changes with Apache 1.3b7
*) Make sure src/Configure doesn't complain about the old directory
Index: htdocs/manual/mod/directives.html
===================================================================
RCS file: /e/apache/REPOS/apache-1.3/htdocs/manual/mod/directives.html,v
retrieving revision 1.43
diff -u -r1.43 directives.html
--- directives.html 1998/04/03 16:07:15 1.43
+++ directives.html 1998/04/17 15:11:41
@@ -107,6 +107,7 @@
<LI><A HREF="mod_autoindex.html#headername">HeaderName</A>
<LI><A HREF="core.html#hostnamelookups">HostNameLookups</A>
<LI><A HREF="core.html#identitycheck">IdentityCheck</A>
+<LI><A HREF="core.html#ifdefine"><IfDefine></A>
<LI><A HREF="core.html#ifmodule"><IfModule></A>
<LI><A HREF="mod_imap.html#imapbase">ImapBase</A>
<LI><A HREF="mod_imap.html#imapdefault">ImapDefault</A>
Index: htdocs/manual/mod/core.html
===================================================================
RCS file: /e/apache/REPOS/apache-1.3/htdocs/manual/mod/core.html,v
retrieving revision 1.107
diff -u -r1.107 core.html
--- core.html 1998/03/28 20:57:04 1.107
+++ core.html 1998/04/17 15:10:06
@@ -42,6 +42,7 @@
<LI><A HREF="#group">Group</A>
<LI><A HREF="#hostnamelookups">HostNameLookups</A>
<LI><A HREF="#identitycheck">IdentityCheck</A>
+<LI><A HREF="#ifdefine"><IfDefine></A>
<LI><A HREF="#ifmodule"><IfModule></A>
<LI><A HREF="#include">Include</A>
<LI><A HREF="#keepalive">KeepAlive</A>
@@ -1025,6 +1026,73 @@
of latency to each hit. So in general this is not very useful on public
servers accessible from the Internet.
<P><HR>
+
+<H2><A NAME="ifdefine"><IfDefine> directive</A></H2>
+<A
+ HREF="directive-dict.html#Syntax"
+ REL="Help"
+><STRONG>Syntax:</STRONG></A> <IfDefine [!]<EM>parameter-name</EM>> <EM>...</EM>
+</IfDefine><BR>
+<A
+ HREF="directive-dict.html#Default"
+ REL="Help"
+><STRONG>Default:</STRONG></A> None<BR>
+<A
+ HREF="directive-dict.html#Context"
+ REL="Help"
+><STRONG>Context:</STRONG></A> all<BR>
+<A
+ HREF="directive-dict.html#Status"
+ REL="Help"
+><STRONG>Status:</STRONG></A> Core<BR>
+<A
+ HREF="directive-dict.html#Compatibility"
+ REL="Help"
+><STRONG>Compatibility:</STRONG></A> <IfDefine> is only available in 1.3 and
+later.<P>
+
+<P>
+
+The <IfDefine <EM>test</EM>>...</IfDefine>
+section is used to mark directives that are conditional. The
+directives within an IfDefine section are only
+processed if the <EM>test</EM> is true. If <EM>test</EM>
+is false, everything between the start and end markers
+is ignored.<P>
+
+The <EM>test</EM> in the <IfDefine> section directive
+can be one of two forms:
+
+<UL>
+<LI><EM>parameter-name</EM>
+<LI><CODE>!</CODE><EM>parameter-name</EM>
+</UL>
+
+<P>In the former case, the directives between the start and end markers are
+only processed if the parameter named <EM>parameter-name</EM> is defined.
+The second format reverses the test, and only processes the directives if
+<EM>parameter-name</EM> is <STRONG>not</STRONG> defined.
+
+<P>The <EM>paramater-name</EM> argument is a define as given on the
+<CODE>httpd</CODE> command line via <CODE>-D</CODE><EM>parameter-</EM>, at the
+time the server was started.
+
+<P><IfDefine> sections are nest-able, which can be used to implement
+simple multiple-parameter tests.
+
+Example:
+
+<PRE>
+ $ httpd -DReverseProxy ...
+
+ # httpd.conf
+ <IfDefine ReverseProxy>
+ LoadModule rewrite_module libexec/mod_rewrite.so
+ LoadModule proxy_module libexec/libproxy.so
+ </IfDefine>
+</PRE>
+
+<P> <HR>
<H2><A NAME="ifmodule"><IfModule> directive</A></H2>
<A
Index: src/include/http_conf_globals.h
===================================================================
RCS file: /e/apache/REPOS/apache-1.3/src/include/http_conf_globals.h,v
retrieving revision 1.27
diff -u -r1.27 http_conf_globals.h
--- http_conf_globals.h 1998/04/11 12:00:19 1.27
+++ http_conf_globals.h 1998/04/17 10:47:15
@@ -95,9 +95,10 @@
extern API_VAR_EXPORT char ap_server_root[MAX_STRING_LEN];
extern char ap_server_confname[MAX_STRING_LEN];
-/* for -C and -c switches */
+/* for -C, -c and -D switches */
extern array_header *ap_server_pre_read_config;
extern array_header *ap_server_post_read_config;
+extern array_header *ap_server_config_defines;
/* We want this to have the least chance of being corrupted if there
* is some memory corruption, so we allocate it statically.
Index: src/main/http_core.c
===================================================================
RCS file: /e/apache/REPOS/apache-1.3/src/main/http_core.c,v
retrieving revision 1.183
diff -u -r1.183 http_core.c
--- http_core.c 1998/04/13 18:05:11 1.183
+++ http_core.c 1998/04/17 10:47:15
@@ -657,6 +657,7 @@
static const char end_filesmatch_section[] = "</FilesMatch>";
static const char end_virtualhost_section[] = "</VirtualHost>";
static const char end_ifmodule_section[] = "</IfModule>";
+static const char end_ifdefine_section[] = "</IfDefine>";
API_EXPORT(const char *) ap_check_cmd_context(cmd_parms *cmd, unsigned forbidden)
@@ -1173,6 +1174,58 @@
return NULL;
}
+static int ap_exists_config_define(char *name)
+{
+ char **defines;
+ int i;
+
+ defines = (char **)ap_server_config_defines->elts;
+ for (i = 0; i < ap_server_config_defines->nelts; i++) {
+ if (strcmp(defines[i], name) == 0)
+ return 1;
+ }
+ return 0;
+}
+
+static const char *end_ifdefine(cmd_parms *cmd, void *dummy)
+{
+ return NULL;
+}
+
+static const char *start_ifdefine(cmd_parms *cmd, void *dummy, char *arg)
+{
+ char *endp;
+ char l[MAX_STRING_LEN];
+ int defined;
+ int not = 0;
+ int nest = 1;
+
+ endp = strrchr(arg, '>');
+ if (endp)
+ *endp = '\0';
+ if (arg[0] == '!') {
+ not = 1;
+ arg++;
+ }
+
+ defined = ap_exists_config_define(arg);
+
+ if ((!not && defined) || (not && !defined))
+ return NULL;
+
+ while (nest && !(ap_cfg_getline(l, MAX_STRING_LEN, cmd->config_file))) {
+ if (!strncasecmp(l, "<IfDefine", 9))
+ nest++;
+ if (!strcasecmp(l, "</IfDefine>"))
+ nest--;
+ }
+ if (nest) {
+ cmd->end_token = end_ifdefine_section;
+ return missing_endsection(cmd, nest);
+ }
+ return NULL;
+}
+
/* httpd.conf commands... beginning with the <VirtualHost> business */
static const char *virtualhost_section (cmd_parms *cmd, void *dummy, char *arg)
@@ -1244,9 +1297,11 @@
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
if (err != NULL) return err;
- if (ap_add_named_module (arg))
+ if (ap_add_named_module(arg))
return NULL;
- return "required module not found";
+ else
+ return ap_pstrcat(cmd->pool, "Required module '",
+ arg, "' not found", NULL);
}
static const char *clear_module_list_command (cmd_parms *cmd, void *dummy)
@@ -1870,6 +1925,8 @@
{ "</Limit>", endlimit_section, NULL, OR_ALL, NO_ARGS, "Marks end of <Limit>" },
{ "<IfModule", start_ifmod, NULL, OR_ALL, RAW_ARGS, "Container for directives based on existance of specified modules" },
{ end_ifmodule_section, end_ifmod, NULL, OR_ALL, NO_ARGS, "Marks end of <IfModule>" },
+{ "<IfDefine", start_ifdefine, NULL, OR_ALL, RAW_ARGS, "Container for directives based on existance of command line defines" },
+{ end_ifdefine_section, end_ifdefine, NULL, OR_ALL, NO_ARGS, "Marks end of <IfDefine>" },
{ "<DirectoryMatch", dirsection, (void*)1, RSRC_CONF, RAW_ARGS, "Container for directives affecting resources located in the specified directories" },
{ end_directorymatch_section, end_nested_section, NULL, ACCESS_CONF, NO_ARGS, "Marks end of <DirectoryMatch>" },
{ "<LocationMatch", urlsection, (void*)1, RSRC_CONF, RAW_ARGS, "Container for directives affecting resources accessed through the specified URL paths" },
Index: src/main/http_main.c
===================================================================
RCS file: /e/apache/REPOS/apache-1.3/src/main/http_main.c,v
retrieving revision 1.324
diff -u -r1.324 http_main.c
--- http_main.c 1998/04/11 12:00:29 1.324
+++ http_main.c 1998/04/17 10:47:14
@@ -278,6 +278,7 @@
array_header *ap_server_pre_read_config;
array_header *ap_server_post_read_config;
+array_header *ap_server_config_defines;
/* *Non*-shared http_main globals... */
@@ -3079,6 +3080,7 @@
pcommands = ap_make_sub_pool(NULL);
ap_server_pre_read_config = ap_make_array(pcommands, 1, sizeof(char *));
ap_server_post_read_config = ap_make_array(pcommands, 1, sizeof(char *));
+ ap_server_config_defines = ap_make_array(pcommands, 1, sizeof(char *));
}
#ifndef MULTITHREAD
@@ -3969,9 +3971,9 @@
ap_setup_prelinked_modules();
#ifdef DEBUG_SIGSTOP
- while ((c = getopt(argc, argv, "C:c:Xd:f:vVhlL:Z:")) != -1) {
+ while ((c = getopt(argc, argv, "C:c:D:Xd:f:vVhlL:Z:")) != -1) {
#else
- while ((c = getopt(argc, argv, "C:c:Xd:f:vVhlL:")) != -1) {
+ while ((c = getopt(argc, argv, "C:c:D:Xd:f:vVhlL:")) != -1) {
#endif
char **new;
switch (c) {
@@ -3983,6 +3985,10 @@
new = (char **)ap_push_array(ap_server_pre_read_config);
*new = ap_pstrdup(pcommands, optarg);
break;
+ case 'D':
+ new = (char **)ap_push_array(ap_server_config_defines);
+ *new = ap_pstrdup(pcommands, optarg);
+ break;
case 'd':
ap_cpystrn(ap_server_root, optarg, sizeof(ap_server_root));
break;
@@ -5065,7 +5071,7 @@
ap_setup_prelinked_modules();
- while ((c = getopt(argc, argv, "C:c:Xd:f:vVhlZ:ius")) != -1) {
+ while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVhlZ:ius")) != -1) {
char **new;
switch (c) {
case 'c':
@@ -5074,6 +5080,10 @@
break;
case 'C':
new = (char **)ap_push_array(ap_server_pre_read_config);
+ *new = ap_pstrdup(pcommands, optarg);
+ break;
+ case 'D':
+ new = (char **)ap_push_array(ap_server_config_defines);
*new = ap_pstrdup(pcommands, optarg);
break;
#ifdef WIN32
Index: src/support/httpd.8
===================================================================
RCS file: /e/apache/REPOS/apache-1.3/src/support/httpd.8,v
retrieving revision 1.7
diff -u -r1.7 httpd.8
--- httpd.8 1998/04/10 10:34:36 1.7
+++ httpd.8 1998/04/17 10:47:14
@@ -69,6 +69,8 @@
.BI \-C " directive"
] [
.BI \-c " directive"
+] [
+.BI \-D " parameter"
]
.B httpd
@@ -134,6 +136,11 @@
.TP
.BI \-c " directive"
Process the configuration \fIdirective\fP after reading config files.
+.TP
+.BI \-D " parameter"
+Sets a configuration \fIparameter\fP which can be used with
+<IfDefine>...</IfDefine> sections in the configuration files
+to conditionally skip or process commands.
.TP
.B \-h
Output a list of directives together with expected arguments and
Re: [PATCH] sections
Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
Ralf S. Engelschall wrote:
>
> <IfDefine> Sections
> ===================
>
> This patch adds a useful <IfDefine>...</IfDefine> section to the core module
> very similar to the existing <IfModule>...<IfModule> sections.
>
> Example:
>
> $ httpd ... -DReverseProxy ....
>
> # httpd.conf
> <IfDefine ReverseProxy>
> LoadModule rewrite_module libexec/mod_rewrite.so
> LoadModule proxy_module libexec/libproxy.so
> </IfDefine>
I rather like this idea for post-1.3.0. +1 on concept (untested)
for the next feature cycle.
#ken P-)}
Ken Coar <http://Web.Golux.Com/coar/>
Apache Group member <http://www.apache.org/>
"Apache Server for Dummies" <http://Web.Golux.Com/coar/ASFD/>
Re: [PATCH] sections
Posted by Brian Behlendorf <br...@hyperreal.org>.
I am against designing a programming language piece by piece. I'm not
convinced that we will reach a point in time where the config language
won't have "just one more thing" that will make it more useful to somebody.
For example, I could make a nice use of a macro.
I believe the configuration file syntax should avoid being procedural - you
think config syntaxes are hard to debug now, just wait! mod_perl and its
ilk have shown that programmatic interfaces to the configuration interface
can be done outside the core very effectively. There is also no good
reason why a procedural configuration interface can't *generate* a flat
descriptional configuration file, and if you roll it up into httpd.start
script then it's just as transparant to the end-user.
A procedural configuration file would also become very difficult to
represent in a GUI. Anyone know of a good Visual Perl tool? :)
I think the config engine should be frozen for the rest of 1.3 to allow the
GUI efforts to grow, and I think for 2.0 we should examine moving the
config language to something like XML.
Brian
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
"Optimism is a strategy for making brian@apache.org
a better future." - Noam Chomsky brian@hyperreal.org
Re: [PATCH] sections
Posted by Dean Gaudet <dg...@arctic.org>.
The namespace could be the environment... so that we don't have to define
yet another namespace.
Dean
On Sat, 18 Apr 1998, Ben Laurie wrote:
> Rodent of Unusual Size wrote:
> >
> > Ben Hyde wrote:
> > >
> > > ><IfDefine> Sections
> > > >===================
> > >
> > > This, one presumes, checks for the presence
> > > of a symbol in a new namespace. Let me
> > > call it "*features*" after a similar one
> > > in Common Lisp.
> > >
> > > Aside: The <IfModule ..> has it's own namespace
> > > and it would be good to only have one, so
> > > I'd urge redefining <IfModule ..> in terms of this
> > > new one by having each module push a symbol
> > > into *feature* implicitly.
> >
> > Hmm. That's not how I interpreted it. A separate namespace,
> > yes - but definitions set on the command line, not by modules.
> > E.g., "httpd -Dsym1".
>
> You misunderstand, I think. What he wants is for modules to push a
> symbol into the namespace, too, so instead of:
>
> <IfModule foo>
>
> you use:
>
> <IfDefined _module_foo>
>
> Cheers,
>
> Ben.
>
> --
> Ben Laurie |Phone: +44 (181) 735 0686| Apache Group member
> Freelance Consultant |Fax: +44 (181) 735 0689|http://www.apache.org
> and Technical Director|Email: ben@algroup.co.uk |
> A.L. Digital Ltd, |Apache-SSL author http://www.apache-ssl.org/
> London, England. |"Apache: TDG" http://www.ora.com/catalog/apache
>
Re: [PATCH] sections
Posted by Ben Laurie <be...@algroup.co.uk>.
Rodent of Unusual Size wrote:
>
> Ben Hyde wrote:
> >
> > ><IfDefine> Sections
> > >===================
> >
> > This, one presumes, checks for the presence
> > of a symbol in a new namespace. Let me
> > call it "*features*" after a similar one
> > in Common Lisp.
> >
> > Aside: The <IfModule ..> has it's own namespace
> > and it would be good to only have one, so
> > I'd urge redefining <IfModule ..> in terms of this
> > new one by having each module push a symbol
> > into *feature* implicitly.
>
> Hmm. That's not how I interpreted it. A separate namespace,
> yes - but definitions set on the command line, not by modules.
> E.g., "httpd -Dsym1".
You misunderstand, I think. What he wants is for modules to push a
symbol into the namespace, too, so instead of:
<IfModule foo>
you use:
<IfDefined _module_foo>
Cheers,
Ben.
--
Ben Laurie |Phone: +44 (181) 735 0686| Apache Group member
Freelance Consultant |Fax: +44 (181) 735 0689|http://www.apache.org
and Technical Director|Email: ben@algroup.co.uk |
A.L. Digital Ltd, |Apache-SSL author http://www.apache-ssl.org/
London, England. |"Apache: TDG" http://www.ora.com/catalog/apache
Re: [PATCH] sections
Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
Ben Hyde wrote:
>
> ><IfDefine> Sections
> >===================
>
> This, one presumes, checks for the presence
> of a symbol in a new namespace. Let me
> call it "*features*" after a similar one
> in Common Lisp.
>
> Aside: The <IfModule ..> has it's own namespace
> and it would be good to only have one, so
> I'd urge redefining <IfModule ..> in terms of this
> new one by having each module push a symbol
> into *feature* implicitly.
Hmm. That's not how I interpreted it. A separate namespace,
yes - but definitions set on the command line, not by modules.
E.g., "httpd -Dsym1".
#ken P-)}
Ken Coar <http://Web.Golux.Com/coar/>
Apache Group member <http://www.apache.org/>
"Apache Server for Dummies" <http://Web.Golux.Com/coar/ASFD/>
Re: [PATCH] sections
Posted by Ben Hyde <bh...@pobox.com>.
><IfDefine> Sections
>===================
This, one presumes, checks for the presence
of a symbol in a new namespace. Let me
call it "*features*" after a similar one
in Common Lisp.
Aside: The <IfModule ..> has it's own namespace
and it would be good to only have one, so
I'd urge redefining <IfModule ..> in terms of this
new one by having each module push a symbol
into *feature* implicitly.
Of course, <if...> forms are needed to avoid loading
parts of that database for which the current
server lacks the tools to validate - even -
their syntax.
*Features* would be good for all kinds of
bracketing, not just per module. For example
portions of the configuration file that
implement cool bundles of rewrite.
While <if...> sounds like the configuration file
is moving toward a procedural design I'd
rather see it move toward a database model
with <if...> suggesting a labeling on a
portion of the database.
*Features* might be the right way to bracket
parts of the config. file that are presented
in single dialogs of the imaginary GUI.
The tension between database v.s. procedural
is kind of a classic one. If we provide users
with a way to push additional symbol into
*features* (e.g. <PushFeature EnableCoolRewrites>)
or as we already do allow them to load additional
modules, then the config file is order dependent
(i.e. procedural).
It might be best to require all directives
that modify *features* to reside in a
prolog of the confiuration file.
A database model is better for a GUI Config
file interface. If the symbols in *features*
had values and the config. file reader did
C preprocessor like rewrites things would get
more complex/interesting.
- ben hyde