summaryrefslogtreecommitdiff
path: root/lib/Apache/Defaults.pm
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-02-21 11:44:04 +0200
committerSergey Poznyakoff <gray@gnu.org>2018-02-21 11:44:04 +0200
commit3c71a4b3c78a8b25258e858135cd239d22bd83c9 (patch)
tree4da1c6f630b29e42208966c1381f258164e4c946 /lib/Apache/Defaults.pm
downloadapache-defaults-3c71a4b3c78a8b25258e858135cd239d22bd83c9.tar.gz
apache-defaults-3c71a4b3c78a8b25258e858135cd239d22bd83c9.tar.bz2
Initial commit
Diffstat (limited to 'lib/Apache/Defaults.pm')
-rw-r--r--lib/Apache/Defaults.pm292
1 files changed, 292 insertions, 0 deletions
diff --git a/lib/Apache/Defaults.pm b/lib/Apache/Defaults.pm
new file mode 100644
index 0000000..13c729e
--- /dev/null
+++ b/lib/Apache/Defaults.pm
@@ -0,0 +1,292 @@
1package Apache::Defaults;
2use strict;
3use warnings;
4use File::Spec;
5use IPC::Open3;
6use Shell::GetEnv;
7use DateTime::Format::Strptime;
8use Symbol 'gensym';
9use Carp;
10
11our $VERSION = '0.10';
12
13sub new {
14 my $class = shift;
15 my $self = bless {}, $class;
16 local %_ = @_;
17 my $v;
18 my @servlist;
19 if ($v = delete $_{server}) {
20 if (ref($v) eq 'ARRAY') {
21 @servlist = @$v;
22 } else {
23 @servlist = ( $v );
24 }
25 } else {
26 @servlist = qw(/usr/sbin/httpd /usr/sbin/apache2);
27 }
28
29 if (my @select = grep { -x $_ } @servlist) {
30 $self->{server} = shift @select;
31 } else {
32 croak "No suitable httpd binary found";
33 }
34
35 if ($v = delete $_{environ}) {
36 $self->{environ} = Shell::GetEnv->new('sh', ". $v", startup => 0)
37 ->envs;
38 }
39
40 croak "unrecognized arguments" if keys(%_);
41 return $self;
42}
43
44sub server { shift->{server} }
45sub environ { shift->{environ} }
46
47sub probe {
48 my ($self, $cb, @opt) = @_;
49
50 open(my $nullout, '>', File::Spec->devnull);
51 open(my $nullin, '<', File::Spec->devnull);
52
53 my $fd = gensym;
54 local %ENV = %{$self->{environ}} if $self->{environ};
55 if (my $pid = open3($nullin, $fd, $nullout, $self->server, @opt)) {
56 while (<$fd>) {
57 chomp;
58 last unless &{$cb}($_);
59 }
60 }
61 close $fd;
62 close $nullin;
63 close $nullout;
64}
65
66sub dequote {
67 my ($self, $arg) = @_;
68 if ($arg =~ s{^"(.*?)"$}{$1}) {
69 $arg =~ s{\\([\\"])}{$1}g;
70 }
71 return $arg;
72}
73
74sub _get_version_info {
75 my $self = shift;
76 unless ($self->{has_version_info}) {
77 $self->probe(sub {
78 local $_ = shift;
79 if (m{^Server version:\s+(.+?)/(\S+)\s+\((.*?)\)}) {
80 $self->{name} = $1;
81 $self->{version} = $2;
82 $self->{platform} = $3;
83 } elsif (/^Server built:\s+(.+)/) {
84 $self->{built} =
85 DateTime::Format::Strptime->new(
86 pattern => '%b %d %Y %H:%M%S',
87 strict => 1,
88 locale => 'en_US',
89 time_zone => 'UTC',
90 on_error => 'undef'
91 )->parse_datetime($1);
92
93 } elsif (/^Server loaded:\s+(.+)$/) {
94 $self->{loaded_with} = $1;
95 } elsif (/^Compiled using:\s+(.+)$/) {
96 $self->{compiled_with} = $1;
97 } elsif (/^Architecture:\s+(.+)$/) {
98 $self->{architecture} = $1;
99 } elsif (/^Server MPM:\s+(.+)$/) {
100 $self->{MPM} = $1;
101 } elsif (/^\s+threaded:\s+(?<b>yes|no)/) {
102 $self->{MPM_threaded} = $+{b} eq 'yes';
103 } elsif (/^\s+forked:\s+(?<b>yes|no)/) {
104 $self->{MPM_forked} = $+{b} eq 'yes';
105 } elsif (/^\s+-D\s+(?<name>.+?)=(?<val>.+)$/) {
106 $self->{defines}{$+{name}} = $self->dequote($+{val});
107 } elsif (/^\s+-D\s+(?<name>.+?)(?:\s*(?<com>.+))?$/) {
108 $self->{defines}{$+{name}} = 1;
109 }
110 return 1;
111 }, '-V');
112 }
113 $self->{has_version_info} = 1;
114}
115
116my @ATTRIBUTES = qw(name
117 version
118 platform
119 built
120 loaded_with
121 compiled_with
122 architecture
123 MPM
124 MPM_threaded
125 MPM_forked);
126{
127 no strict 'refs';
128 foreach my $attribute (@ATTRIBUTES) {
129 *{ __PACKAGE__ . '::' . $attribute } = sub {
130 my $self = shift;
131 $self->_get_version_info;
132 $self->{$attribute};
133 }
134 }
135}
136
137sub server_root { shift->defines('HTTPD_ROOT') }
138
139sub defines {
140 my $self = shift;
141 $self->_get_version_info;
142 return @{$self->{defines}}{@_};
143}
144
145# List of module sources and corresponding identifiers, obtained from the
146# httpd-2.4.6 source.
147my %modlist = (
148 'event.c' => 'mpm_event_module',
149 'prefork.c' => 'mpm_prefork_module',
150 'worker.c' => 'mpm_worker_module',
151 'mod_access_compat.c' => 'access_compat_module',
152 'mod_actions.c' => 'actions_module',
153 'mod_alias.c' => 'alias_module',
154 'mod_allowmethods.c' => 'allowmethods_module',
155 'mod_asis.c' => 'asis_module',
156 'mod_auth_basic.c' => 'auth_basic_module',
157 'mod_auth_digest.c' => 'auth_digest_module',
158 'mod_auth_form.c' => 'auth_form_module',
159 'mod_authn_anon.c' => 'authn_anon_module',
160 'mod_authn_core.c' => 'authn_core_module',
161 'mod_authn_dbd.c' => 'authn_dbd_module',
162 'mod_authn_dbm.c' => 'authn_dbm_module',
163 'mod_authn_file.c' => 'authn_file_module',
164 'mod_authn_socache.c' => 'authn_socache_module',
165 'mod_authnz_ldap.c' => 'authnz_ldap_module',
166 'mod_authz_core.c' => 'authz_core_module',
167 'mod_authz_dbd.c' => 'authz_dbd_module',
168 'mod_authz_dbm.c' => 'authz_dbm_module',
169 'mod_authz_groupfile.c' => 'authz_groupfile_module',
170 'mod_authz_host.c' => 'authz_host_module',
171 'mod_authz_owner.c' => 'authz_owner_module',
172 'mod_authz_user.c' => 'authz_user_module',
173 'mod_autoindex.c' => 'autoindex_module',
174 'mod_buffer.c' => 'buffer_module',
175 'mod_cache.c' => 'cache_module',
176 'mod_cache_disk.c' => 'cache_disk_module',
177 'mod_cache_socache.c' => 'cache_socache_module',
178 'mod_cern_meta.c' => 'cern_meta_module',
179 'mod_cgi.c' => 'cgi_module',
180 'mod_cgid.c' => 'cgid_module',
181 'mod_charset_lite.c' => 'charset_lite_module',
182 'mod_data.c' => 'data_module',
183 'mod_dav.c' => 'dav_module',
184 'mod_dav_fs.c' => 'dav_fs_module',
185 'mod_dav_lock.c' => 'dav_lock_module',
186 'mod_dbd.c' => 'dbd_module',
187 'mod_deflate.c' => 'deflate_module',
188 'mod_dialup.c' => 'dialup_module',
189 'mod_dir.c' => 'dir_module',
190 'mod_dumpio.c' => 'dumpio_module',
191 'mod_echo.c' => 'echo_module',
192 'mod_env.c' => 'env_module',
193 'mod_example.c' => 'example_module',
194 'mod_expires.c' => 'expires_module',
195 'mod_ext_filter.c' => 'ext_filter_module',
196 'mod_file_cache.c' => 'file_cache_module',
197 'mod_filter.c' => 'filter_module',
198 'mod_headers.c' => 'headers_module',
199 'mod_heartbeat' => 'heartbeat_module',
200 'mod_heartmonitor.c' => 'heartmonitor_module',
201 'mod_ident.c' => 'ident_module',
202 'mod_imagemap.c' => 'imagemap_module',
203 'mod_include.c' => 'include_module',
204 'mod_info.c' => 'info_module',
205 'mod_isapi.c' => 'isapi_module',
206 'mod_lbmethod_bybusyness.c' => 'lbmethod_bybusyness_module',
207 'mod_lbmethod_byrequests.c' => 'lbmethod_byrequests_module',
208 'mod_lbmethod_bytraffic.c' => 'lbmethod_bytraffic_module',
209 'mod_lbmethod_heartbeat.c' => 'lbmethod_heartbeat_module',
210 'util_ldap.c' => 'ldap_module',
211 'mod_log_config.c' => 'log_config_module',
212 'mod_log_debug.c' => 'log_debug_module',
213 'mod_log_forensic.c' => 'log_forensic_module',
214 'mod_logio.c' => 'logio_module',
215 'mod_lua.c' => 'lua_module',
216 'mod_macro.c' => 'macro_module',
217 'mod_mime.c' => 'mime_module',
218 'mod_mime_magic.c' => 'mime_magic_module',
219 'mod_negotiation.c' => 'negotiation_module',
220 'mod_nw_ssl.c' => 'nwssl_module',
221 'mod_privileges.c' => 'privileges_module',