PluginProbe
HTTP Headers / 1.7.0
HTTP Headers v1.7.0
1.19.5 trunk 1.0.0 1.1.0 1.1.1 1.1.2 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 1.12.0 1.12.1 1.12.2 1.13.0 1.13.1 1.13.2 1.13.3 1.13.4 1.14.0 1.14.1 1.14.2 1.15.0 All 60 releases
http-headers / http-headers.php

http-headers.php in HTTP Headers 1.7.0, at http-headers.php

726 lines 26.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: HTTP Headers
4 Plugin URI: https://zinoui.com/blog/http-headers-for-wordpress
5 Description: A plugin for HTTP headers management including security, access-control (CORS), caching, compression, and authentication.
6 Version: 1.7.0
7 Author: Dimitar Ivanov
8 Author URI: https://zinoui.com
9 License: GPLv2 or later
10 Text Domain: http-headers
11 */
12
13 /*
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License
16 as published by the Free Software Foundation; either version 2
17 of the License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program. If not, see <http://www.gnu.org/copyleft/gpl.html>.
26
27 Copyright (c) 2017 Zino UI
28 */
29
30 if (get_option('hh_strict_transport_security_max_age') === false) {
31 $value = get_option('hh_strict_transport_security_value');
32 $max_age = preg_match('/max-age=(\d+)/', $value, $match) ? $match[1] : 0;
33 $sub_domains = strpos($value, 'includeSubDomains') !== false ? 1 : 0;
34 add_option('hh_strict_transport_security_max_age', $max_age, null, 'yes');
35 add_option('hh_strict_transport_security_sub_domains', $sub_domains, null, 'yes');
36 add_option('hh_strict_transport_security_preload', 0, null, 'yes');
37 }
38
39 if (get_option('hh_referrer_policy') === false) {
40 add_option('hh_referrer_policy', 0, null, 'yes');
41 add_option('hh_referrer_policy_value', null, null, 'yes');
42 }
43
44 if (get_option('hh_content_security_policy') === false) {
45 add_option('hh_content_security_policy', 0, null, 'yes');
46 add_option('hh_content_security_policy_value', null, null, 'yes');
47 }
48
49 if (get_option('hh_content_security_policy_report_only') === false) {
50 add_option('hh_content_security_policy_report_only', 0, null, 'yes');
51 }
52
53 if (get_option('hh_public_key_pins_report_only') === false) {
54 add_option('hh_public_key_pins_report_only', 0, null, 'yes');
55 }
56
57 if (get_option('hh_x_xxs_protection_uri') === false) {
58 add_option('hh_x_xxs_protection_uri', null, null, 'yes');
59 }
60
61 if (get_option('hh_method') === false) {
62 add_option('hh_method', 'php', null, 'yes');
63 }
64
65 if (get_option('hh_connection') === false) {
66 add_option('hh_connection', 0, null, 'yes');
67 add_option('hh_connection_value', null, null, 'yes');
68 }
69
70 if (get_option('hh_cache_control') === false) {
71 add_option('hh_cache_control', 0, null, 'yes');
72 add_option('hh_cache_control_value', null, null, 'yes');
73 }
74
75 if (get_option('hh_age') === false) {
76 add_option('hh_age', 0, null, 'yes');
77 add_option('hh_age_value', null, null, 'yes');
78 }
79
80 if (get_option('hh_pragma') === false) {
81 add_option('hh_pragma', 0, null, 'yes');
82 add_option('hh_pragma_value', null, null, 'yes');
83 }
84
85 if (get_option('hh_expires') === false) {
86 add_option('hh_expires', 0, null, 'yes');
87 add_option('hh_expires_value', null, null, 'yes');
88 add_option('hh_expires_type', null, null, 'yes');
89 }
90
91 if (get_option('hh_content_encoding') === false) {
92 add_option('hh_content_encoding', 0, null, 'yes');
93 add_option('hh_content_encoding_value', null, null, 'yes');
94 add_option('hh_content_encoding_ext', null, null, 'yes');
95 }
96
97 if (get_option('hh_vary') === false) {
98 add_option('hh_vary', 0, null, 'yes');
99 add_option('hh_vary_value', null, null, 'yes');
100 }
101
102 if (get_option('hh_x_powered_by') === false) {
103 add_option('hh_x_powered_by', 0, null, 'yes');
104 add_option('hh_x_powered_by_option', null, null, 'yes');
105 add_option('hh_x_powered_by_value', null, null, 'yes');
106 }
107
108 if (get_option('hh_www_authenticate') === false) {
109 add_option('hh_www_authenticate', 0, null, 'yes');
110 add_option('hh_www_authenticate_type', null, null, 'yes');
111 add_option('hh_www_authenticate_realm', null, null, 'yes');
112 add_option('hh_www_authenticate_user', null, null, 'yes');
113 add_option('hh_www_authenticate_pswd', null, null, 'yes');
114 }
115
116 if (get_option('hh_cookie_security') === false) {
117 add_option('hh_cookie_security', 0, null, 'yes');
118 add_option('hh_cookie_security_value', null, null, 'yes');
119 }
120
121 if (get_option('hh_expect_ct') === false) {
122 add_option('hh_expect_ct', 0, null, 'yes');
123 add_option('hh_expect_ct_max_age', null, null, 'yes');
124 add_option('hh_expect_ct_report_uri', null, null, 'yes');
125 add_option('hh_expect_ct_enforce', null, null, 'yes');
126 }
127
128 function get_http_headers() {
129 $statuses = array();
130 $unset = array();
131 $headers = array();
132 $append = array();
133 if (get_option('hh_x_frame_options') == 1) {
134 $x_frame_options_value = strtoupper(get_option('hh_x_frame_options_value'));
135 if ($x_frame_options_value == 'ALLOW-FROM') {
136 $x_frame_options_value .= ' ' . get_option('hh_x_frame_options_domain');
137 }
138 $headers['X-Frame-Options'] = $x_frame_options_value;
139 }
140 if (get_option('hh_x_powered_by') == 1) {
141 if (get_option('hh_x_powered_by_option') == 'set') {
142 $headers['X-Powered-By'] = get_option('hh_x_powered_by_value');
143 } else {
144 $unset[] = 'X-Powered-By';
145 }
146 }
147 if (get_option('hh_x_xxs_protection') == 1) {
148 $headers['X-XSS-Protection'] = get_option('hh_x_xxs_protection_value');
149 if ($headers['X-XSS-Protection'] == '1; report=') {
150 $headers['X-XSS-Protection'] .= get_option('hh_x_xxs_protection_uri');
151 }
152 }
153 if (get_option('hh_x_content_type_options') == 1) {
154 $headers['X-Content-Type-Options'] = get_option('hh_x_content_type_options_value');
155 }
156 if (get_option('hh_connection') == 1) {
157 $headers['Connection'] = get_option('hh_connection_value');
158 }
159 if (get_option('hh_pragma') == 1) {
160 $headers['Pragma'] = get_option('hh_pragma_value');
161 }
162 if (get_option('hh_age') == 1) {
163 $headers['Age'] = sprintf("%u", get_option('hh_age_value'));
164 }
165 if (get_option('hh_cache_control') == 1) {
166 $hh_cache_control_value = get_option('hh_cache_control_value', array());
167 $tmp = array();
168 foreach ($hh_cache_control_value as $k => $v) {
169 if (in_array($k, array('max-age', 's-maxage'))) {
170 if (strlen($v) > 0) {
171 $tmp[] = sprintf("%s=%u", $k, $v);
172 }
173 } else {
174 $tmp[] = $k;
175 }
176 }
177 $hh_cache_control_value = join(', ', $tmp);
178 $headers['Cache-Control'] = $hh_cache_control_value;
179 }
180 if (get_option('hh_strict_transport_security') == 1) {
181 $hh_strict_transport_security = array();
182
183 $hh_strict_transport_security_max_age = get_option('hh_strict_transport_security_max_age');
184 if ($hh_strict_transport_security_max_age !== false)
185 {
186 $hh_strict_transport_security[] = sprintf('max-age=%u', get_option('hh_strict_transport_security_max_age'));
187 if (get_option('hh_strict_transport_security_sub_domains'))
188 {
189 $hh_strict_transport_security[] = 'includeSubDomains';
190 }
191 if (get_option('hh_strict_transport_security_preload'))
192 {
193 $hh_strict_transport_security[] = 'preload';
194 }
195 } else {
196 $hh_strict_transport_security = array(get_option('hh_strict_transport_security_value'));
197 }
198 $headers['Strict-Transport-Security'] = join('; ', $hh_strict_transport_security);
199 }
200 if (get_option('hh_x_ua_compatible') == 1) {
201 $headers['X-UA-Compatible'] = get_option('hh_x_ua_compatible_value');
202 }
203 if (get_option('hh_public_key_pins') == 1) {
204 $public_key_pins_sha256_1 = get_option('hh_public_key_pins_sha256_1');
205 $public_key_pins_sha256_2 = get_option('hh_public_key_pins_sha256_2');
206 $public_key_pins_max_age = get_option('hh_public_key_pins_max_age');
207 $public_key_pins_sub_domains = get_option('hh_public_key_pins_sub_domains');
208 $public_key_pins_report_uri = get_option('hh_public_key_pins_report_uri');
209 $public_key_pins_report_only = get_option('hh_public_key_pins_report_only');
210 if (!empty($public_key_pins_sha256_1) && !empty($public_key_pins_sha256_2) && !empty($public_key_pins_max_age)) {
211
212 $public_key_pins = array();
213 $public_key_pins[] = sprintf('pin-sha256="%s"', $public_key_pins_sha256_1);
214 $public_key_pins[] = sprintf('pin-sha256="%s"', $public_key_pins_sha256_2);
215 $public_key_pins[] = sprintf("max-age=%u", $public_key_pins_max_age);
216 if ($public_key_pins_sub_domains) {
217 $public_key_pins[] = "includeSubDomains";
218 }
219 if (!empty($public_key_pins_report_uri)) {
220 $public_key_pins[] = sprintf('report-uri="%s"', $public_key_pins_report_uri);
221 }
222 $headers['Public-Key-Pins'.($public_key_pins_report_only ? '-Report-Only' : NULL)] = join('; ', $public_key_pins);
223 }
224 }
225
226 if (get_option('hh_content_security_policy') == 1)
227 {
228 $csp = array();
229 $values = get_option('hh_content_security_policy_value');
230 $csp_report_only = get_option('hh_content_security_policy_report_only');
231 foreach ($values as $key => $val)
232 {
233 if (!empty($val))
234 {
235 $csp[] = sprintf("%s %s", $key, $val);
236 }
237 }
238 if (!empty($csp))
239 {
240 $headers['Content-Security-Policy'.($csp_report_only ? '-Report-Only' : NULL)] = join('; ', $csp);
241 }
242 }
243
244 if (get_option('hh_access_control_allow_origin') == 1)
245 {
246 $value = get_option('hh_access_control_allow_origin_value');
247 switch ($value)
248 {
249 case 'HTTP_ORIGIN':
250 $value = @$_SERVER['HTTP_ORIGIN'];
251 break;
252 case 'origin':
253 $value = get_option('hh_access_control_allow_origin_url');
254 break;
255 }
256 if (!empty($value))
257 {
258 $headers['Access-Control-Allow-Origin'] = $value;
259 }
260 }
261 if (get_option('hh_access_control_allow_credentials') == 1)
262 {
263 $headers['Access-Control-Allow-Credentials'] = get_option('hh_access_control_allow_credentials_value');
264 }
265 if (get_option('hh_access_control_max_age') == 1)
266 {
267 $value = get_option('hh_access_control_max_age_value');
268 if (!empty($value))
269 {
270 $headers['Access-Control-Max-Age'] = intval($value);
271 }
272 }
273 if (get_option('hh_access_control_allow_methods') == 1)
274 {
275 $value = get_option('hh_access_control_allow_methods_value');
276 if (!empty($value))
277 {
278 $headers['Access-Control-Allow-Methods'] = join(', ', array_keys($value));
279 }
280 }
281 if (get_option('hh_access_control_allow_headers') == 1)
282 {
283 $value = get_option('hh_access_control_allow_headers_value');
284 if (!empty($value))
285 {
286 $headers['Access-Control-Allow-Headers'] = join(', ', array_keys($value));
287 }
288 }
289 if (get_option('hh_access_control_expose_headers') == 1)
290 {
291 $value = get_option('hh_access_control_expose_headers_value');
292 if (!empty($value))
293 {
294 $headers['Access-Control-Expose-Headers'] = join(', ', array_keys($value));
295 }
296 }
297 if (get_option('hh_p3p') == 1)
298 {
299 $value = get_option('hh_p3p_value');
300 if (!empty($value))
301 {
302 $headers['P3P'] = 'CP="' . join(' ', array_keys($value)) . '"';
303 }
304 }
305 if (get_option('hh_referrer_policy') == 1) {
306 $headers['Referrer-Policy'] = get_option('hh_referrer_policy_value');
307 }
308 if (get_option('hh_www_authenticate') == 1) {
309
310 switch (get_option('hh_www_authenticate_type')) {
311 case 'Basic':
312 if (!(isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])
313 && $_SERVER['PHP_AUTH_USER'] == get_option('hh_www_authenticate_user')
314 && $_SERVER['PHP_AUTH_PW'] == get_option('hh_www_authenticate_pswd'))) {
315 $headers['WWW-Authenticate'] = sprintf("Basic realm='%s'", get_option('hh_www_authenticate_realm'));
316 $statuses['HTTP/1.1'] = '401 Unauthorized';
317 }
318 break;
319 case 'Digest':
320 if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
321 $realm = get_option('hh_www_authenticate_realm');
322 $headers['WWW-Authenticate'] = sprintf("Digest realm='%s',qop='auth',nonce='%s',opaque='%s'",
323 $realm, uniqid(), md5($realm));
324 $statuses['HTTP/1.1'] = '401 Unauthorized';
325 }
326 break;
327 }
328 }
329 if (get_option('hh_vary') == 1)
330 {
331 $value = get_option('hh_vary_value');
332 if (!empty($value))
333 {
334 $append['Vary'] = join(', ', array_keys($value));
335 }
336 }
337
338 if (get_option('hh_expect_ct') == 1) {
339 $expect_ct_max_age = get_option('hh_expect_ct_max_age');
340 $expect_ct_report_uri = get_option('hh_expect_ct_report_uri');
341 if (!empty($expect_ct_report_uri) && !empty($expect_ct_max_age)) {
342
343 $expect_ct = array();
344 $expect_ct[] = sprintf("max-age=%u", $expect_ct_max_age);
345 if (get_option('hh_expect_ct_enforce') == 1) {
346 $expect_ct[] = "enforce";
347 }
348 $expect_ct[] = sprintf('report-uri="%s"', $expect_ct_report_uri);
349 $headers['Expect-CT'] = join(', ', $expect_ct);
350 }
351 }
352
353 return array($headers, $statuses, $unset, $append);
354 }
355
356 function http_digest_parse($txt) {
357 $txt = stripslashes($txt);
358
359 $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
360 $data = array();
361 $keys = implode('|', array_keys($needed_parts));
362
363 preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);
364
365 foreach ($matches as $m) {
366 $data[$m[1]] = $m[3] ? $m[3] : $m[4];
367 unset($needed_parts[$m[1]]);
368 }
369
370 return $needed_parts ? false : $data;
371 }
372
373 function php_auth_digest() {
374 if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || get_option('hh_www_authenticate_user') != $data['username']) {
375 die('Wrong Credentials!');
376 }
377
378 $A1 = md5($data['username'] . ':' . get_option('hh_www_authenticate_realm') . ':' . get_option('hh_www_authenticate_pswd'));
379 $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
380 $valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);
381 if ($data['response'] != $valid_response) {
382 die('Wrong Credentials!');
383 }
384 }
385
386 function php_content_encoding() {
387 if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) {
388 ob_start('ob_gzhandler');
389 } else {
390 ob_start();
391 }
392 }
393
394 function http_headers() {
395 if (get_option('hh_method') !== 'php') {
396 return;
397 }
398 // PHP method below
399 list($headers, $statuses, $unset, $append) = get_http_headers();
400 foreach ($headers as $key => $value) {
401 header(sprintf("%s: %s", $key, $value));
402 }
403 foreach ($append as $key => $value) {
404 header(sprintf("%s: %s", $key, $value), false);
405 }
406 foreach ($unset as $header) {
407 if (function_exists('header_remove')) {
408 header_remove($header);
409 } else {
410 header("$header:");
411 }
412 }
413 foreach ($statuses as $key => $value) {
414 header(sprintf("%s %s", $key, $value));
415 exit;
416 }
417
418 if (get_option('hh_www_authenticate') == 1) {
419 php_auth_digest();
420 }
421
422 if (get_option('hh_content_encoding') == 1) {
423 php_content_encoding();
424 }
425 }
426
427 function http_headers_admin_add_page() {
428 add_options_page('HTTP Headers', 'HTTP Headers', 'manage_options', 'http-headers', 'http_headers_admin_page');
429 }
430
431 function http_headers_admin() {
432 register_setting('http-headers-mtd', 'hh_method');
433 register_setting('http-headers-xfo', 'hh_x_frame_options');
434 register_setting('http-headers-xfo', 'hh_x_frame_options_value');
435 register_setting('http-headers-xfo', 'hh_x_frame_options_domain');
436 register_setting('http-headers-xss', 'hh_x_xxs_protection');
437 register_setting('http-headers-xss', 'hh_x_xxs_protection_value');
438 register_setting('http-headers-xss', 'hh_x_xxs_protection_uri');
439 register_setting('http-headers-cto', 'hh_x_content_type_options');
440 register_setting('http-headers-cto', 'hh_x_content_type_options_value');
441 register_setting('http-headers-sts', 'hh_strict_transport_security');
442 register_setting('http-headers-sts', 'hh_strict_transport_security_value'); //obsolete
443 register_setting('http-headers-sts', 'hh_strict_transport_security_max_age');
444 register_setting('http-headers-sts', 'hh_strict_transport_security_sub_domains');
445 register_setting('http-headers-sts', 'hh_strict_transport_security_preload');
446 register_setting('http-headers-pkp', 'hh_public_key_pins');
447 register_setting('http-headers-pkp', 'hh_public_key_pins_sha256_1');
448 register_setting('http-headers-pkp', 'hh_public_key_pins_sha256_2');
449 register_setting('http-headers-pkp', 'hh_public_key_pins_max_age');
450 register_setting('http-headers-pkp', 'hh_public_key_pins_sub_domains');
451 register_setting('http-headers-pkp', 'hh_public_key_pins_report_uri');
452 register_setting('http-headers-pkp', 'hh_public_key_pins_report_only');
453 register_setting('http-headers-uac', 'hh_x_ua_compatible');
454 register_setting('http-headers-uac', 'hh_x_ua_compatible_value');
455 register_setting('http-headers-p3p', 'hh_p3p');
456 register_setting('http-headers-p3p', 'hh_p3p_value');
457 register_setting('http-headers-rp', 'hh_referrer_policy');
458 register_setting('http-headers-rp', 'hh_referrer_policy_value');
459 register_setting('http-headers-csp', 'hh_content_security_policy');
460 register_setting('http-headers-csp', 'hh_content_security_policy_value');
461 register_setting('http-headers-csp', 'hh_content_security_policy_report_only');
462 register_setting('http-headers-acao', 'hh_access_control_allow_origin');
463 register_setting('http-headers-acao', 'hh_access_control_allow_origin_value');
464 register_setting('http-headers-acao', 'hh_access_control_allow_origin_url');
465 register_setting('http-headers-acac', 'hh_access_control_allow_credentials');
466 register_setting('http-headers-acac', 'hh_access_control_allow_credentials_value');
467 register_setting('http-headers-acam', 'hh_access_control_allow_methods');
468 register_setting('http-headers-acam', 'hh_access_control_allow_methods_value');
469 register_setting('http-headers-acah', 'hh_access_control_allow_headers');
470 register_setting('http-headers-acah', 'hh_access_control_allow_headers_value');
471 register_setting('http-headers-aceh', 'hh_access_control_expose_headers');
472 register_setting('http-headers-aceh', 'hh_access_control_expose_headers_value');
473 register_setting('http-headers-acma', 'hh_access_control_max_age');
474 register_setting('http-headers-acma', 'hh_access_control_max_age_value');
475 register_setting('http-headers-ce', 'hh_content_encoding');
476 register_setting('http-headers-ce', 'hh_content_encoding_value');
477 register_setting('http-headers-ce', 'hh_content_encoding_ext');
478 register_setting('http-headers-vary', 'hh_vary');
479 register_setting('http-headers-vary', 'hh_vary_value');
480 register_setting('http-headers-xpb', 'hh_x_powered_by');
481 register_setting('http-headers-xpb', 'hh_x_powered_by_option');
482 register_setting('http-headers-xpb', 'hh_x_powered_by_value');
483 register_setting('http-headers-wwa', 'hh_www_authenticate');
484 register_setting('http-headers-wwa', 'hh_www_authenticate_type');
485 register_setting('http-headers-wwa', 'hh_www_authenticate_realm');
486 register_setting('http-headers-wwa', 'hh_www_authenticate_user');
487 register_setting('http-headers-wwa', 'hh_www_authenticate_pswd');
488 register_setting('http-headers-cc', 'hh_cache_control');
489 register_setting('http-headers-cc', 'hh_cache_control_value');
490 register_setting('http-headers-age', 'hh_age');
491 register_setting('http-headers-age', 'hh_age_value');
492 register_setting('http-headers-pra', 'hh_pragma');
493 register_setting('http-headers-pra', 'hh_pragma_value');
494 register_setting('http-headers-exp', 'hh_expires');
495 register_setting('http-headers-exp', 'hh_expires_value');
496 register_setting('http-headers-exp', 'hh_expires_type');
497 register_setting('http-headers-con', 'hh_connection');
498 register_setting('http-headers-con', 'hh_connection_value');
499 register_setting('http-headers-cose', 'hh_cookie_security');
500 register_setting('http-headers-cose', 'hh_cookie_security_value');
501 register_setting('http-headers-ect', 'hh_expect_ct');
502 register_setting('http-headers-ect', 'hh_expect_ct_max_age');
503 register_setting('http-headers-ect', 'hh_expect_ct_report_uri');
504 register_setting('http-headers-ect', 'hh_expect_ct_enforce');
505
506 # When method is changed
507 if (isset($_GET['settings-updated'], $_GET['tab']) && $_GET['settings-updated'] == 'true' && $_GET['tab'] == 'advanced') {
508 update_headers_directives();
509
510 update_auth_credentials();
511 update_auth_directives();
512
513 update_content_encoding_directives();
514
515 update_expires_directives();
516
517 update_cookie_security_directives();
518 }
519
520 # When particular header is changed
521 if (isset($_GET['settings-updated'], $_GET['header'])
522 && $_GET['settings-updated'] == 'true'
523 && get_option('hh_method') == 'htaccess') {
524
525 switch ($_GET['header']) {
526 case 'www-authenticate':
527 update_auth_credentials();
528 update_auth_directives();
529 break;
530 case 'content-encoding':
531 case 'vary':
532 update_content_encoding_directives();
533 break;
534 case 'expires':
535 update_expires_directives();
536 break;
537 case 'cookie-security':
538 update_cookie_security_directives();
539 break;
540 default:
541 update_headers_directives();
542 }
543 }
544 }
545
546 function update_headers_directives() {
547 $lines = array();
548 if (get_option('hh_method') == 'htaccess') {
549 list($headers, $statuses, $unset, $append) = get_http_headers();
550
551 foreach ($unset as $header) {
552 $lines[] = sprintf(' Header unset %s', $header);
553 }
554 foreach ($headers as $key => $value) {
555 if (in_array($key, array('WWW-Authenticate'))) {
556 continue;
557 }
558 $lines[] = sprintf(' Header set %s %s', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
559 }
560 foreach ($append as $key => $value) {
561 $lines[] = sprintf(' Header append %s %s', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
562 }
563
564 if (!empty($lines)) {
565 array_unshift($lines, '<FilesMatch "\.(php|html)$">', ' <IfModule mod_headers.c>');
566 array_push($lines, ' </IfModule>', '</FilesMatch>');
567 }
568 }
569 return insert_with_markers(get_home_path().'.htaccess', "HttpHeaders", $lines);
570 }
571
572 function update_content_encoding_directives() {
573 $lines = array();
574 if (get_option('hh_method') == 'htaccess' && get_option('hh_content_encoding') == 1) {
575
576 $content_encoding_value = get_option('hh_content_encoding_value');
577 if (!$content_encoding_value) {
578 $content_encoding_value = array();
579 }
580
581 $content_encoding_ext = get_option('hh_content_encoding_ext');
582 if (!$content_encoding_ext) {
583 $content_encoding_ext = array();
584 }
585 if (!empty($content_encoding_ext)) {
586 $lines[] = sprintf('<FilesMatch "\.(%s)$">', join('|', array_keys($content_encoding_ext)));
587 $lines[] = ' <IfModule mod_deflate.c>';
588 $lines[] = ' SetOutputFilter DEFLATE';
589 $lines[] = ' </IfModule>';
590 $lines[] = '</FilesMatch>';
591 }
592 if (!empty($content_encoding_value)) {
593 if (!empty($lines)) {
594 $lines[] = '';
595 }
596 $lines[] = '<IfModule mod_deflate.c>';
597 foreach ($content_encoding_value as $item => $whatever) {
598 $lines[] = sprintf(' AddOutputFilterByType DEFLATE %s', $item);
599 }
600 $lines[] = '</IfModule>';
601 }
602 }
603
604 return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersCompression", $lines);
605 }
606
607 function update_expires_directives() {
608 $lines = array();
609 if (get_option('hh_method') == 'htaccess' && get_option('hh_expires') == 1) {
610
611 $types = get_option('hh_expires_type', array());
612 $values = get_option('hh_expires_value', array());
613
614 $lines[] = '<IfModule mod_expires.c>';
615 $lines[] = ' ExpiresActive On';
616 foreach ($types as $type => $whatever) {
617 list($base, $period, $suffix) = explode('_', $values[$type]);
618 if (in_array($base, array('access', 'modification'))) {
619 $lines[] = $type != 'default'
620 ? sprintf(' ExpiresByType %s "%s plus %u %s"', $type, $base, $period, $suffix)
621 : sprintf(' ExpiresDefault "%s plus %u %s"', $base, $period, $suffix);
622 } elseif ($base == 'invalid') {
623 $lines[] = $type != 'default'
624 ? sprintf(' ExpiresByType %s A0', $type)
625 : sprintf(' ExpiresDefault A0');
626 }
627 }
628 $lines[] = '</IfModule>';
629 }
630 return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersExpires", $lines);
631 }
632
633 function update_auth_directives() {
634 $lines = array();
635 if (get_option('hh_method') == 'htaccess' && get_option('hh_www_authenticate') == 1) {
636
637 $type = get_option('hh_www_authenticate_type');
638
639 $file = $type == 'Basic' ? '.hh-htpasswd' : '.hh-htdigest';
640
641 $lines[] = '<FilesMatch "^\.hh-ht(digest|passwd)$">';
642 $lines[] = ' Order deny,allow';
643 $lines[] = ' Deny from all';
644 $lines[] = '</FilesMatch>';
645
646 $lines[] = sprintf('<IfModule mod_auth_%s.c>', strtolower($type));
647 $lines[] = sprintf(' AuthType %s', get_option('hh_www_authenticate_type'));
648 $lines[] = sprintf(' AuthName "%s"', get_option('hh_www_authenticate_realm'));
649 $lines[] = sprintf(' AuthUserFile "%s%s"', get_home_path(), $file);
650 $lines[] = sprintf(' Require user %s', get_option('hh_www_authenticate_user'));
651 $lines[] = '</IfModule>';
652 }
653
654 return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersAuth", $lines);
655 }
656
657 function update_cookie_security_directives() {
658 $lines = array();
659 if (get_option('hh_method') == 'htaccess' && get_option('hh_cookie_security') == 1) {
660 $value = get_option('hh_cookie_security_value', array());
661 if (isset($value['HttpOnly'])) {
662 $lines[] = 'php_flag session.cookie_httponly on';
663 }
664 if (isset($value['Secure'])) {
665 $lines[] = 'php_flag session.cookie_secure on';
666 }
667 }
668 return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersCookieSecurity", $lines);
669 }
670
671 function update_auth_credentials() {
672 if (get_option('hh_method') == 'htaccess' && get_option('hh_www_authenticate') == 1) {
673 $type = get_option('hh_www_authenticate_type');
674 $user = get_option('hh_www_authenticate_user');
675 $pswd = get_option('hh_www_authenticate_pswd');
676 $realm = get_option('hh_www_authenticate_realm');
677
678 switch ($type) {
679 case 'Basic':
680 $ht_file = get_home_path().'.hh-htpasswd';
681 $auth = sprintf('%s:{SHA}%s', $user, base64_encode(sha1($pswd, true)));
682 break;
683 case 'Digest':
684 $ht_file = get_home_path().'.hh-htdigest';
685 $auth = sprintf('%s:%s:%s', $user, $realm, md5($user.':'.$realm.':'.$pswd));
686 break;
687 }
688 return @file_put_contents($ht_file, $auth);
689 }
690 return false;
691 }
692
693 function http_headers_settings_link( $links ) {
694 $url = get_admin_url() . 'options-general.php?page=http-headers';
695 $settings_link = '<a href="' . $url . '">' . __('Settings') . '</a>';
696 array_unshift( $links, $settings_link );
697 return $links;
698 }
699
700 function http_headers_after_setup_theme() {
701 add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'http_headers_settings_link');
702 }
703
704 function http_headers_enqueue($hook) {
705 if ( 'http-headers.php' != $hook ) {
706 # FIXME
707 //return;
708 }
709
710 wp_enqueue_script('http_headers_admin_scripts', plugin_dir_url( __FILE__ ) . 'assets/scripts.js');
711 wp_enqueue_style('http_headers_admin_styles', plugin_dir_url( __FILE__ ) . 'assets/styles.css');
712 }
713
714 if ( is_admin() ){ // admin actions
715 add_action('admin_menu', 'http_headers_admin_add_page');
716 add_action('admin_init', 'http_headers_admin');
717 add_action('admin_enqueue_scripts', 'http_headers_enqueue');
718 add_action('after_setup_theme', 'http_headers_after_setup_theme');
719 } else {
720 // non-admin enqueues, actions, and filters
721 add_action('send_headers', 'http_headers');
722 }
723
724 function http_headers_admin_page() {
725 include 'views/index.php';
726 }