PluginProbe
HTTP Headers / 1.10.3
HTTP Headers v1.10.3
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.10.3, at http-headers.php

1,279 lines 46.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.10.3
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-2018 Zino UI
28 */
29
30 if (!defined('ABSPATH')) {
31 exit;
32 }
33
34 if (get_option('hh_strict_transport_security_max_age') === false) {
35 $value = get_option('hh_strict_transport_security_value');
36 $max_age = preg_match('/max-age=(\d+)/', $value, $match) ? $match[1] : 0;
37 $sub_domains = strpos($value, 'includeSubDomains') !== false ? 1 : 0;
38 add_option('hh_strict_transport_security_max_age', $max_age, null, 'yes');
39 add_option('hh_strict_transport_security_sub_domains', $sub_domains, null, 'yes');
40 add_option('hh_strict_transport_security_preload', 0, null, 'yes');
41 }
42
43 if (get_option('hh_referrer_policy') === false) {
44 add_option('hh_referrer_policy', 0, null, 'yes');
45 add_option('hh_referrer_policy_value', null, null, 'yes');
46 }
47
48 if (get_option('hh_content_security_policy') === false) {
49 add_option('hh_content_security_policy', 0, null, 'yes');
50 add_option('hh_content_security_policy_value', null, null, 'yes');
51 }
52
53 if (get_option('hh_content_security_policy_report_only') === false) {
54 add_option('hh_content_security_policy_report_only', 0, null, 'yes');
55 }
56
57 if (get_option('hh_public_key_pins_report_only') === false) {
58 add_option('hh_public_key_pins_report_only', 0, null, 'yes');
59 }
60
61 if (get_option('hh_x_xxs_protection_uri') === false) {
62 add_option('hh_x_xxs_protection_uri', null, null, 'yes');
63 }
64
65 if (get_option('hh_method') === false) {
66 add_option('hh_method', 'php', null, 'yes');
67 }
68
69 if (get_option('hh_connection') === false) {
70 add_option('hh_connection', 0, null, 'yes');
71 add_option('hh_connection_value', null, null, 'yes');
72 }
73
74 if (get_option('hh_cache_control') === false) {
75 add_option('hh_cache_control', 0, null, 'yes');
76 add_option('hh_cache_control_value', null, null, 'yes');
77 }
78
79 if (get_option('hh_age') === false) {
80 add_option('hh_age', 0, null, 'yes');
81 add_option('hh_age_value', null, null, 'yes');
82 }
83
84 if (get_option('hh_pragma') === false) {
85 add_option('hh_pragma', 0, null, 'yes');
86 add_option('hh_pragma_value', null, null, 'yes');
87 }
88
89 if (get_option('hh_expires') === false) {
90 add_option('hh_expires', 0, null, 'yes');
91 add_option('hh_expires_value', null, null, 'yes');
92 add_option('hh_expires_type', null, null, 'yes');
93 }
94
95 if (get_option('hh_content_encoding') === false) {
96 add_option('hh_content_encoding', 0, null, 'yes');
97 add_option('hh_content_encoding_value', null, null, 'yes');
98 add_option('hh_content_encoding_ext', null, null, 'yes');
99 }
100
101 if (get_option('hh_vary') === false) {
102 add_option('hh_vary', 0, null, 'yes');
103 add_option('hh_vary_value', null, null, 'yes');
104 }
105
106 if (get_option('hh_x_powered_by') === false) {
107 add_option('hh_x_powered_by', 0, null, 'yes');
108 add_option('hh_x_powered_by_option', null, null, 'yes');
109 add_option('hh_x_powered_by_value', null, null, 'yes');
110 }
111
112 if (get_option('hh_www_authenticate') === false) {
113 add_option('hh_www_authenticate', 0, null, 'yes');
114 add_option('hh_www_authenticate_type', null, null, 'yes');
115 add_option('hh_www_authenticate_realm', null, null, 'yes');
116 add_option('hh_www_authenticate_user', null, null, 'yes');
117 add_option('hh_www_authenticate_pswd', null, null, 'yes');
118 }
119
120 if (get_option('hh_cookie_security') === false) {
121 add_option('hh_cookie_security', 0, null, 'yes');
122 add_option('hh_cookie_security_value', null, null, 'yes');
123 }
124
125 if (get_option('hh_expect_ct') === false) {
126 add_option('hh_expect_ct', 0, null, 'yes');
127 add_option('hh_expect_ct_max_age', null, null, 'yes');
128 add_option('hh_expect_ct_report_uri', null, null, 'yes');
129 add_option('hh_expect_ct_enforce', null, null, 'yes');
130 }
131
132 if (get_option('hh_timing_allow_origin') === false) {
133 add_option('hh_timing_allow_origin', 0, null, 'yes');
134 add_option('hh_timing_allow_origin_value', null, null, 'yes');
135 add_option('hh_timing_allow_origin_url', null, null, 'yes');
136 }
137
138 if (get_option('hh_custom_headers') === false) {
139 add_option('hh_custom_headers', 0, null, 'yes');
140 add_option('hh_custom_headers_value', null, null, 'yes');
141 }
142
143 if (get_option('hh_x_permitted_cross_domain_policies') === false) {
144 add_option('hh_x_permitted_cross_domain_policies', 0, null, 'yes');
145 add_option('hh_x_permitted_cross_domain_policies_value', null, null, 'yes');
146 }
147
148 if (get_option('hh_x_download_options') === false) {
149 add_option('hh_x_download_options', 0, null, 'yes');
150 add_option('hh_x_download_options_value', null, null, 'yes');
151 }
152
153 if (get_option('hh_x_dns_prefetch_control') === false) {
154 add_option('hh_x_dns_prefetch_control', 0, null, 'yes');
155 add_option('hh_x_dns_prefetch_control_value', null, null, 'yes');
156 }
157
158 if (get_option('hh_report_to') === false) {
159 add_option('hh_report_to', 0, null, 'yes');
160 add_option('hh_report_to_value', null, null, 'yes');
161 }
162
163 if (get_option('hh_feature_policy') === false) {
164 add_option('hh_feature_policy', 0, null, 'yes');
165 add_option('hh_feature_policy_feature', null, null, 'yes');
166 add_option('hh_feature_policy_origin', null, null, 'yes');
167 add_option('hh_feature_policy_value', null, null, 'yes');
168 }
169
170 function get_http_headers() {
171 $statuses = array();
172 $unset = array();
173 $headers = array();
174 $append = array();
175 if (get_option('hh_x_frame_options') == 1) {
176 $x_frame_options_value = strtoupper(get_option('hh_x_frame_options_value'));
177 if ($x_frame_options_value == 'ALLOW-FROM') {
178 $x_frame_options_value .= ' ' . get_option('hh_x_frame_options_domain');
179 }
180 $headers['X-Frame-Options'] = $x_frame_options_value;
181 }
182 if (get_option('hh_x_powered_by') == 1) {
183 if (get_option('hh_x_powered_by_option') == 'set') {
184 $headers['X-Powered-By'] = get_option('hh_x_powered_by_value');
185 } else {
186 $unset[] = 'X-Powered-By';
187 }
188 }
189 if (get_option('hh_x_xxs_protection') == 1) {
190 $headers['X-XSS-Protection'] = get_option('hh_x_xxs_protection_value');
191 if ($headers['X-XSS-Protection'] == '1; report=') {
192 $headers['X-XSS-Protection'] .= get_option('hh_x_xxs_protection_uri');
193 }
194 }
195 if (get_option('hh_x_content_type_options') == 1) {
196 $headers['X-Content-Type-Options'] = get_option('hh_x_content_type_options_value');
197 }
198 if (get_option('hh_x_download_options') == 1) {
199 $headers['X-Download-Options'] = get_option('hh_x_download_options_value');
200 }
201 if (get_option('hh_x_permitted_cross_domain_policies') == 1) {
202 $headers['X-Permitted-Cross-Domain-Policies'] = get_option('hh_x_permitted_cross_domain_policies_value');
203 }
204 if (get_option('hh_x_dns_prefetch_control') == 1) {
205 $headers['X-DNS-Prefetch-Control'] = get_option('hh_x_dns_prefetch_control_value');
206 }
207 if (get_option('hh_connection') == 1) {
208 $headers['Connection'] = get_option('hh_connection_value');
209 }
210 if (get_option('hh_pragma') == 1) {
211 $headers['Pragma'] = get_option('hh_pragma_value');
212 }
213 if (get_option('hh_age') == 1) {
214 $headers['Age'] = sprintf("%u", get_option('hh_age_value'));
215 }
216 if (get_option('hh_cache_control') == 1) {
217 $hh_cache_control_value = get_option('hh_cache_control_value', array());
218 $tmp = array();
219 foreach ($hh_cache_control_value as $k => $v) {
220 if (in_array($k, array('max-age', 's-maxage'))) {
221 if (strlen($v) > 0) {
222 $tmp[] = sprintf("%s=%u", $k, $v);
223 }
224 } else {
225 $tmp[] = $k;
226 }
227 }
228 $hh_cache_control_value = join(', ', $tmp);
229 $headers['Cache-Control'] = $hh_cache_control_value;
230 }
231 if (get_option('hh_strict_transport_security') == 1) {
232 $hh_strict_transport_security = array();
233
234 $hh_strict_transport_security_max_age = get_option('hh_strict_transport_security_max_age');
235 if ($hh_strict_transport_security_max_age !== false)
236 {
237 $hh_strict_transport_security[] = sprintf('max-age=%u', get_option('hh_strict_transport_security_max_age'));
238 if (get_option('hh_strict_transport_security_sub_domains'))
239 {
240 $hh_strict_transport_security[] = 'includeSubDomains';
241 }
242 if (get_option('hh_strict_transport_security_preload'))
243 {
244 $hh_strict_transport_security[] = 'preload';
245 }
246 } else {
247 $hh_strict_transport_security = array(get_option('hh_strict_transport_security_value'));
248 }
249 $headers['Strict-Transport-Security'] = join('; ', $hh_strict_transport_security);
250 }
251 if (get_option('hh_x_ua_compatible') == 1) {
252 $headers['X-UA-Compatible'] = get_option('hh_x_ua_compatible_value');
253 }
254 if (get_option('hh_public_key_pins') == 1) {
255 $public_key_pins_sha256_1 = get_option('hh_public_key_pins_sha256_1');
256 $public_key_pins_sha256_2 = get_option('hh_public_key_pins_sha256_2');
257 $public_key_pins_max_age = get_option('hh_public_key_pins_max_age');
258 $public_key_pins_sub_domains = get_option('hh_public_key_pins_sub_domains');
259 $public_key_pins_report_uri = get_option('hh_public_key_pins_report_uri');
260 $public_key_pins_report_only = get_option('hh_public_key_pins_report_only');
261 if (!empty($public_key_pins_sha256_1) && !empty($public_key_pins_sha256_2) && !empty($public_key_pins_max_age)) {
262
263 $public_key_pins = array();
264 $public_key_pins[] = sprintf('pin-sha256="%s"', $public_key_pins_sha256_1);
265 $public_key_pins[] = sprintf('pin-sha256="%s"', $public_key_pins_sha256_2);
266 $public_key_pins[] = sprintf("max-age=%u", $public_key_pins_max_age);
267 if ($public_key_pins_sub_domains) {
268 $public_key_pins[] = "includeSubDomains";
269 }
270 if (!empty($public_key_pins_report_uri)) {
271 $public_key_pins[] = sprintf('report-uri="%s"', $public_key_pins_report_uri);
272 }
273 $headers['Public-Key-Pins'.($public_key_pins_report_only ? '-Report-Only' : NULL)] = join('; ', $public_key_pins);
274 }
275 }
276
277 if (get_option('hh_content_security_policy') == 1)
278 {
279 $csp = array();
280 $values = get_option('hh_content_security_policy_value');
281 $csp_report_only = get_option('hh_content_security_policy_report_only');
282 foreach ($values as $key => $val)
283 {
284 if (!empty($val))
285 {
286 $csp[] = sprintf("%s %s", $key, $val);
287 }
288 }
289 if (!empty($csp))
290 {
291 $headers['Content-Security-Policy'.($csp_report_only ? '-Report-Only' : NULL)] = join('; ', $csp);
292 }
293 }
294
295 if (get_option('hh_access_control_allow_origin') == 1)
296 {
297 $value = get_option('hh_access_control_allow_origin_value');
298 switch ($value)
299 {
300 case 'origin':
301 $value = get_option('hh_access_control_allow_origin_url', array());
302 if (is_scalar($value))
303 {
304 $value = array($value);
305 }
306 break;
307 }
308 if (!empty($value))
309 {
310 $headers['Access-Control-Allow-Origin'] = $value;
311 }
312 }
313 if (get_option('hh_access_control_allow_credentials') == 1)
314 {
315 $headers['Access-Control-Allow-Credentials'] = get_option('hh_access_control_allow_credentials_value');
316 }
317 if (get_option('hh_access_control_max_age') == 1)
318 {
319 $value = get_option('hh_access_control_max_age_value');
320 if (!empty($value))
321 {
322 $headers['Access-Control-Max-Age'] = intval($value);
323 }
324 }
325 if (get_option('hh_access_control_allow_methods') == 1)
326 {
327 $value = get_option('hh_access_control_allow_methods_value');
328 if (!empty($value))
329 {
330 $headers['Access-Control-Allow-Methods'] = join(', ', array_keys($value));
331 }
332 }
333 if (get_option('hh_access_control_allow_headers') == 1)
334 {
335 $value = get_option('hh_access_control_allow_headers_value');
336 if (!empty($value))
337 {
338 $headers['Access-Control-Allow-Headers'] = join(', ', array_keys($value));
339 }
340 }
341 if (get_option('hh_access_control_expose_headers') == 1)
342 {
343 $value = get_option('hh_access_control_expose_headers_value');
344 if (!empty($value))
345 {
346 $headers['Access-Control-Expose-Headers'] = join(', ', array_keys($value));
347 }
348 }
349 if (get_option('hh_p3p') == 1)
350 {
351 $value = get_option('hh_p3p_value');
352 if (!empty($value))
353 {
354 $headers['P3P'] = 'CP="' . join(' ', array_keys($value)) . '"';
355 }
356 }
357 if (get_option('hh_referrer_policy') == 1) {
358 $headers['Referrer-Policy'] = get_option('hh_referrer_policy_value');
359 }
360 if (get_option('hh_www_authenticate') == 1) {
361
362 switch (get_option('hh_www_authenticate_type')) {
363 case 'Basic':
364 if (!(isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])
365 && $_SERVER['PHP_AUTH_USER'] == get_option('hh_www_authenticate_user')
366 && $_SERVER['PHP_AUTH_PW'] == get_option('hh_www_authenticate_pswd'))) {
367 $headers['WWW-Authenticate'] = sprintf("Basic realm='%s'", get_option('hh_www_authenticate_realm'));
368 $statuses['HTTP/1.1'] = '401 Unauthorized';
369 }
370 break;
371 case 'Digest':
372 if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
373 $realm = get_option('hh_www_authenticate_realm');
374 $headers['WWW-Authenticate'] = sprintf("Digest realm='%s',qop='auth',nonce='%s',opaque='%s'",
375 $realm, uniqid(), md5($realm));
376 $statuses['HTTP/1.1'] = '401 Unauthorized';
377 }
378 break;
379 }
380 }
381 if (get_option('hh_vary') == 1)
382 {
383 $value = get_option('hh_vary_value');
384 if (!empty($value))
385 {
386 $append['Vary'] = join(', ', array_keys($value));
387 }
388 }
389
390 if (get_option('hh_expect_ct') == 1) {
391 $expect_ct_max_age = get_option('hh_expect_ct_max_age');
392 $expect_ct_report_uri = get_option('hh_expect_ct_report_uri');
393 if (!empty($expect_ct_report_uri) && !empty($expect_ct_max_age)) {
394
395 $expect_ct = array();
396 $expect_ct[] = sprintf("max-age=%u", $expect_ct_max_age);
397 if (get_option('hh_expect_ct_enforce') == 1) {
398 $expect_ct[] = "enforce";
399 }
400 $expect_ct[] = sprintf('report-uri="%s"', $expect_ct_report_uri);
401 $headers['Expect-CT'] = join(', ', $expect_ct);
402 }
403 }
404 if (get_option('hh_custom_headers') == 1) {
405 $custom_headers = get_option('hh_custom_headers_value');
406 if (isset($custom_headers['name'], $custom_headers['value']) && !empty($custom_headers['name'])) {
407 foreach ($custom_headers['name'] as $key => $name) {
408 $name = trim($name);
409 $value = trim($custom_headers['value'][$key]);
410 if (empty($name) || empty($value)) {
411 continue;
412 }
413 $headers[$name] = $value;
414 }
415 }
416 }
417 if (get_option('hh_report_to') == 1) {
418 $report_to = get_option('hh_report_to_value');
419 $tmp = array();
420 foreach ($report_to as $item)
421 {
422 $tmp[] = sprintf('{"url": "%s", "group": "%s", "max-age": %u%s}',
423 $item['url'], $item['group'], $item['max-age'], isset($item['includeSubDomains']) ? ', includeSubDomains' : NULL);
424 }
425 $headers['Report-To'] = join(', ', $tmp);
426 }
427 if (get_option('hh_feature_policy') == 1) {
428 $feature_policy_feature = get_option('hh_feature_policy_feature');
429 $feature_policy_value = get_option('hh_feature_policy_value');
430 $feature_policy_origin = get_option('hh_feature_policy_origin');
431 $tmp = array();
432 foreach ($feature_policy_feature as $feature => $whatever)
433 {
434 $value = NULL;
435 switch ($feature_policy_value[$feature])
436 {
437 case '*':
438 case "'none'":
439 $value = $feature_policy_value[$feature];
440 break;
441 case "'self'":
442 $value = $feature_policy_value[$feature];
443 if (!empty($feature_policy_origin[$feature]))
444 {
445 $value .= " " . $feature_policy_origin[$feature];
446 }
447 break;
448 case 'origin(s)':
449 $value = $feature_policy_origin[$feature];
450 break;
451 }
452
453 $tmp[] = sprintf("%s %s", $feature, $value);
454 }
455 $headers['Feature-Policy'] = join('; ', $tmp);
456 }
457
458 return array($headers, $statuses, $unset, $append);
459 }
460
461 function http_digest_parse($txt) {
462 $txt = stripslashes($txt);
463
464 $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
465 $data = array();
466 $keys = implode('|', array_keys($needed_parts));
467
468 preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);
469
470 foreach ($matches as $m) {
471 $data[$m[1]] = $m[3] ? $m[3] : $m[4];
472 unset($needed_parts[$m[1]]);
473 }
474
475 return $needed_parts ? false : $data;
476 }
477
478 function php_auth_digest() {
479 if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || get_option('hh_www_authenticate_user') != $data['username']) {
480 die('Wrong Credentials!');
481 }
482
483 $A1 = md5($data['username'] . ':' . get_option('hh_www_authenticate_realm') . ':' . get_option('hh_www_authenticate_pswd'));
484 $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
485 $valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);
486 if ($data['response'] != $valid_response) {
487 die('Wrong Credentials!');
488 }
489 }
490
491 function php_content_encoding() {
492 if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) {
493 ob_start('ob_gzhandler');
494 } else {
495 ob_start();
496 }
497 }
498
499 function http_headers() {
500 if (get_option('hh_method') !== 'php') {
501 return;
502 }
503 // PHP method below
504 list($headers, $statuses, $unset, $append) = get_http_headers();
505 $isCors = false;
506 foreach ($headers as $key => $value) {
507 if ($key == 'Access-Control-Allow-Origin') {
508 if (isset($_SERVER['HTTP_ORIGIN'])) {
509 if ($value == '*') {
510 $isCors = true;
511 header(sprintf("%s: *", $key));
512 }
513
514 if (is_array($value) && in_array($_SERVER['HTTP_ORIGIN'], $value)) {
515 $isCors = true;
516 header(sprintf("%s: %s", $key, $_SERVER['HTTP_ORIGIN']));
517 }
518 }
519 continue;
520 }
521 if (in_array($key, array('Access-Control-Allow-Headers', 'Access-Control-Allow-Methods', 'Access-Control-Allow-Credentials', 'Access-Control-Max-Age', 'Access-Control-Expose-Headers'))) {
522 if ($isCors) {
523 header(sprintf("%s: %s", $key, $value));
524 }
525 continue;
526 }
527 header(sprintf("%s: %s", $key, $value));
528 }
529 foreach ($append as $key => $value) {
530 header(sprintf("%s: %s", $key, $value), false);
531 }
532 foreach ($unset as $header) {
533 if (function_exists('header_remove')) {
534 header_remove($header);
535 } else {
536 header("$header:");
537 }
538 }
539 foreach ($statuses as $key => $value) {
540 header(sprintf("%s %s", $key, $value));
541 exit;
542 }
543
544 if (get_option('hh_www_authenticate') == 1) {
545 php_auth_digest();
546 }
547
548 if (get_option('hh_content_encoding') == 1) {
549 php_content_encoding();
550 }
551 }
552
553 function http_headers_admin_add_page() {
554 add_options_page('HTTP Headers', 'HTTP Headers', 'manage_options', 'http-headers', 'http_headers_admin_page');
555 }
556
557 function http_headers_admin() {
558 register_setting('http-headers-mtd', 'hh_method');
559 register_setting('http-headers-xfo', 'hh_x_frame_options');
560 register_setting('http-headers-xfo', 'hh_x_frame_options_value');
561 register_setting('http-headers-xfo', 'hh_x_frame_options_domain');
562 register_setting('http-headers-xss', 'hh_x_xxs_protection');
563 register_setting('http-headers-xss', 'hh_x_xxs_protection_value');
564 register_setting('http-headers-xss', 'hh_x_xxs_protection_uri');
565 register_setting('http-headers-cto', 'hh_x_content_type_options');
566 register_setting('http-headers-cto', 'hh_x_content_type_options_value');
567 register_setting('http-headers-sts', 'hh_strict_transport_security');
568 register_setting('http-headers-sts', 'hh_strict_transport_security_value'); //obsolete
569 register_setting('http-headers-sts', 'hh_strict_transport_security_max_age');
570 register_setting('http-headers-sts', 'hh_strict_transport_security_sub_domains');
571 register_setting('http-headers-sts', 'hh_strict_transport_security_preload');
572 register_setting('http-headers-pkp', 'hh_public_key_pins');
573 register_setting('http-headers-pkp', 'hh_public_key_pins_sha256_1');
574 register_setting('http-headers-pkp', 'hh_public_key_pins_sha256_2');
575 register_setting('http-headers-pkp', 'hh_public_key_pins_max_age');
576 register_setting('http-headers-pkp', 'hh_public_key_pins_sub_domains');
577 register_setting('http-headers-pkp', 'hh_public_key_pins_report_uri');
578 register_setting('http-headers-pkp', 'hh_public_key_pins_report_only');
579 register_setting('http-headers-uac', 'hh_x_ua_compatible');
580 register_setting('http-headers-uac', 'hh_x_ua_compatible_value');
581 register_setting('http-headers-p3p', 'hh_p3p');
582 register_setting('http-headers-p3p', 'hh_p3p_value');
583 register_setting('http-headers-rp', 'hh_referrer_policy');
584 register_setting('http-headers-rp', 'hh_referrer_policy_value');
585 register_setting('http-headers-csp', 'hh_content_security_policy');
586 register_setting('http-headers-csp', 'hh_content_security_policy_value');
587 register_setting('http-headers-csp', 'hh_content_security_policy_report_only');
588 register_setting('http-headers-acao', 'hh_access_control_allow_origin');
589 register_setting('http-headers-acao', 'hh_access_control_allow_origin_value');
590 register_setting('http-headers-acao', 'hh_access_control_allow_origin_url');
591 register_setting('http-headers-acac', 'hh_access_control_allow_credentials');
592 register_setting('http-headers-acac', 'hh_access_control_allow_credentials_value');
593 register_setting('http-headers-acam', 'hh_access_control_allow_methods');
594 register_setting('http-headers-acam', 'hh_access_control_allow_methods_value');
595 register_setting('http-headers-acah', 'hh_access_control_allow_headers');
596 register_setting('http-headers-acah', 'hh_access_control_allow_headers_value');
597 register_setting('http-headers-aceh', 'hh_access_control_expose_headers');
598 register_setting('http-headers-aceh', 'hh_access_control_expose_headers_value');
599 register_setting('http-headers-acma', 'hh_access_control_max_age');
600 register_setting('http-headers-acma', 'hh_access_control_max_age_value');
601 register_setting('http-headers-ce', 'hh_content_encoding');
602 register_setting('http-headers-ce', 'hh_content_encoding_value');
603 register_setting('http-headers-ce', 'hh_content_encoding_ext');
604 register_setting('http-headers-vary', 'hh_vary');
605 register_setting('http-headers-vary', 'hh_vary_value');
606 register_setting('http-headers-xpb', 'hh_x_powered_by');
607 register_setting('http-headers-xpb', 'hh_x_powered_by_option');
608 register_setting('http-headers-xpb', 'hh_x_powered_by_value');
609 register_setting('http-headers-wwa', 'hh_www_authenticate');
610 register_setting('http-headers-wwa', 'hh_www_authenticate_type');
611 register_setting('http-headers-wwa', 'hh_www_authenticate_realm');
612 register_setting('http-headers-wwa', 'hh_www_authenticate_user');
613 register_setting('http-headers-wwa', 'hh_www_authenticate_pswd');
614 register_setting('http-headers-cc', 'hh_cache_control');
615 register_setting('http-headers-cc', 'hh_cache_control_value');
616 register_setting('http-headers-age', 'hh_age');
617 register_setting('http-headers-age', 'hh_age_value');
618 register_setting('http-headers-pra', 'hh_pragma');
619 register_setting('http-headers-pra', 'hh_pragma_value');
620 register_setting('http-headers-exp', 'hh_expires');
621 register_setting('http-headers-exp', 'hh_expires_value');
622 register_setting('http-headers-exp', 'hh_expires_type');
623 register_setting('http-headers-con', 'hh_connection');
624 register_setting('http-headers-con', 'hh_connection_value');
625 register_setting('http-headers-cose', 'hh_cookie_security');
626 register_setting('http-headers-cose', 'hh_cookie_security_value');
627 register_setting('http-headers-ect', 'hh_expect_ct');
628 register_setting('http-headers-ect', 'hh_expect_ct_max_age');
629 register_setting('http-headers-ect', 'hh_expect_ct_report_uri');
630 register_setting('http-headers-ect', 'hh_expect_ct_enforce');
631 register_setting('http-headers-tao', 'hh_timing_allow_origin');
632 register_setting('http-headers-tao', 'hh_timing_allow_origin_value');
633 register_setting('http-headers-tao', 'hh_timing_allow_origin_url');
634 register_setting('http-headers-che', 'hh_custom_headers');
635 register_setting('http-headers-che', 'hh_custom_headers_value');
636 register_setting('http-headers-xdo', 'hh_x_download_options');
637 register_setting('http-headers-xdo', 'hh_x_download_options_value');
638 register_setting('http-headers-xpcd', 'hh_x_permitted_cross_domain_policies');
639 register_setting('http-headers-xpcd', 'hh_x_permitted_cross_domain_policies_value');
640 register_setting('http-headers-xdpc', 'hh_x_dns_prefetch_control');
641 register_setting('http-headers-xdpc', 'hh_x_dns_prefetch_control_value');
642 register_setting('http-headers-rt', 'hh_report_to');
643 register_setting('http-headers-rt', 'hh_report_to_value');
644 register_setting('http-headers-fp', 'hh_feature_policy');
645 register_setting('http-headers-fp', 'hh_feature_policy_value');
646 register_setting('http-headers-fp', 'hh_feature_policy_feature');
647 register_setting('http-headers-fp', 'hh_feature_policy_origin');
648 }
649
650 function http_headers_option($option) {
651 if (isset($_POST['hh_method']))
652 {
653 check_admin_referer('http-headers-mtd-options');
654 # When method is changed
655 update_headers_directives();
656 update_auth_credentials();
657 update_auth_directives();
658 update_content_encoding_directives();
659 update_expires_directives();
660 update_cookie_security_directives();
661 update_timing_directives();
662
663 } elseif (get_option('hh_method') == 'htaccess') {
664 # When particular header is changed
665 switch (true) {
666 case array_key_exists('hh_www_authenticate', $_POST):
667 check_admin_referer('http-headers-wwa-options');
668 update_auth_credentials();
669 update_auth_directives();
670 break;
671 case array_key_exists('hh_content_encoding', $_POST):
672 check_admin_referer('http-headers-ce-options');
673 update_content_encoding_directives();
674 break;
675 case array_key_exists('hh_vary', $_POST):
676 check_admin_referer('http-headers-vary-options');
677 update_content_encoding_directives();
678 break;
679 case array_key_exists('hh_expires', $_POST):
680 check_admin_referer('http-headers-exp-options');
681 update_expires_directives();
682 break;
683 case array_key_exists('hh_cookie_security', $_POST):
684 check_admin_referer('http-headers-cose-options');
685 update_cookie_security_directives();
686 break;
687 case array_key_exists('hh_timing_allow_origin', $_POST):
688 check_admin_referer('http-headers-tao-options');
689 update_timing_directives();
690 break;
691 case array_key_exists('option_page', $_POST) && strpos($_POST['option_page'], 'http-headers-') === 0:
692 check_admin_referer($_POST['option_page'].'-options');
693 update_headers_directives();
694 break;
695 }
696 }
697 }
698
699 function nginx_headers_directives() {
700 $lines = array();
701 list($headers, $statuses, $unset, $append) = get_http_headers();
702
703 foreach ($unset as $header) {
704 $lines[] = sprintf(' more_clear_headers "%s";', $header);
705 }
706 $cors = $cors_header = $cors_inner = $cors_footer = array();
707 $all = array();
708 foreach ($headers as $key => $value) {
709 if (in_array($key, array('WWW-Authenticate'))) {
710 continue;
711 }
712 if (in_array($key, array('X-Content-Type-Options'))) {
713 $all[] = sprintf('add_header %s %s always;', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
714 continue;
715 }
716 if ($key == 'Access-Control-Allow-Origin' && is_array($value)) {
717 $cors_header[] = sprintf('if ($http_origin ~* ^(%s)$) {', str_replace('.', '\.', join('|', $value)));
718 $cors_footer[] = '}';
719 $cors_inner[] = ' add_header Access-Control-Allow-Origin "$http_origin";';
720 continue;
721 }
722 if (in_array($key, array('Access-Control-Allow-Headers', 'Access-Control-Allow-Methods', 'Access-Control-Allow-Credentials', 'Access-Control-Max-Age', 'Access-Control-Expose-Headers'))) {
723 $cors_inner[] = sprintf(' add_header %s %s;', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
724 continue;
725 }
726 $lines[] = sprintf(' add_header %s %s;', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
727 }
728 foreach ($append as $key => $value) {
729 $lines[] = sprintf(' add_header %s %s;', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
730 }
731 if (!empty($cors_inner))
732 {
733 $cors = array_merge(
734 $cors_header,
735 $cors_inner,
736 $cors_footer
737 );
738 }
739 if (!empty($lines)) {
740 $lines = array_merge(
741 $all,
742 $cors,
743 array('location ~* \.(php|html)$ {'),
744 $lines,
745 array('}')
746 );
747 }
748 return $lines;
749 }
750
751 function nginx_content_encoding_directives() {
752 $lines = array();
753 if (get_option('hh_content_encoding') == 1) {
754
755 $lines[] = 'gzip on;';
756
757 $content_encoding_value = get_option('hh_content_encoding_value');
758 if (!$content_encoding_value) {
759 $content_encoding_value = array();
760 }
761
762 $content_encoding_ext = get_option('hh_content_encoding_ext');
763 if (!$content_encoding_ext) {
764 $content_encoding_ext = array();
765 }
766 if (!empty($content_encoding_ext)) {
767 //$lines[] = sprintf('<FilesMatch "\.(%s)$">', join('|', array_keys($content_encoding_ext)));
768 }
769 if (!empty($content_encoding_value)) {
770 $lines[] = sprintf('gzip_types %s;', join(' ', array_keys($content_encoding_value)));
771 }
772 }
773 return $lines;
774 }
775
776 function nginx_expires_directives() {
777 $lines = array();
778 if (get_option('hh_expires') == 1) {
779
780 $types = get_option('hh_expires_type', array());
781 $values = get_option('hh_expires_value', array());
782
783 $lines[] = 'map $sent_http_content_type $expires {';
784 foreach ($types as $type => $whatever) {
785 list($base, $period, $suffix) = explode('_', $values[$type]);
786 if (in_array($base, array('access', 'modification'))) {
787 $lines[] = $type != 'default'
788 ? sprintf(' %s %u%s;', $type, $period, $suffix[0])
789 : sprintf(' default %u%s;', $period, $suffix[0]);
790 } elseif ($base == 'invalid') {
791 $lines[] = $type != 'default'
792 ? sprintf(' %s 0;', $type)
793 : sprintf(' default 0;');
794 }
795 }
796 $lines[] = '}';
797
798 $lines[] = 'expires $expires;';
799 }
800 return $lines;
801 }
802
803 function nginx_timing_directives() {
804 $lines = array();
805 if (get_option('hh_timing_allow_origin') == 1) {
806 $value = get_option('hh_timing_allow_origin_value');
807 switch ($value)
808 {
809 case 'origin':
810 $value = get_option('hh_timing_allow_origin_url');
811 break;
812 }
813 if (!empty($value))
814 {
815 $lines[] = 'location ~* \.(js|css|jpe?g|png|gif|eot|otf|svg|ttf|woff2?)$ {';
816 $lines[] = sprintf(' add_header Timing-Allow-Origin "%s";', $value);
817 $lines[] = '}';
818 }
819 }
820 return $lines;
821 }
822
823 function nginx_auth_directives() {
824 $lines = array();
825 if (get_option('hh_www_authenticate') == 1) {
826
827 $type = get_option('hh_www_authenticate_type');
828
829 $file = $type == 'Basic' ? '.hh-htpasswd' : '.hh-htdigest';
830
831 $lines[] = 'location ~ ^\.hh-ht(digest|passwd)$ {';
832 $lines[] = ' deny all;';
833 $lines[] = '}';
834
835 $lines[] = sprintf('location %s {', get_home_path());
836 if ($type == 'Basic') {
837 $lines[] = sprintf(' auth_basic "%s";', get_option('hh_www_authenticate_realm'));
838 $lines[] = sprintf(' auth_basic_user_file %s%s;', get_home_path(), $file);
839 } else {
840 $lines[] = sprintf(' auth_digest "%s";', get_option('hh_www_authenticate_realm'));
841 $lines[] = sprintf(' auth_digest_user_file %s%s;', get_home_path(), $file);
842 }
843 $lines[] = '}';
844 }
845 return $lines;
846 }
847
848 function nginx_auth_credentials() {
849 return apache_auth_credentials();
850 }
851
852 function nginx_cookie_security_directives() {
853 $lines = array();
854
855 //TODO
856
857 return $lines;
858 }
859
860 function iis_headers_directives() {
861 //TODO scheduled for v2.0.0
862 }
863
864 function iis_content_encoding_directives() {
865 //TODO scheduled for v2.0.0
866 }
867
868 function iis_expires_directives() {
869 //TODO scheduled for v2.0.0
870 }
871
872 function iis_timing_directives() {
873 //TODO scheduled for v2.0.0
874 }
875
876 function iis_auth_directives() {
877 //TODO scheduled for v2.0.0
878 }
879
880 function iis_auth_credentials() {
881 //TODO scheduled for v2.0.0
882 }
883
884 function iis_cookie_security_directives() {
885 //TODO scheduled for v2.0.0
886 }
887
888 function apache_headers_directives() {
889 $lines = array();
890 list($headers, $statuses, $unset, $append) = get_http_headers();
891
892 foreach ($unset as $header) {
893 $lines[] = sprintf(' Header unset %s', $header);
894 }
895 $all = array();
896 foreach ($headers as $key => $value) {
897 if (in_array($key, array('WWW-Authenticate'))) {
898 continue;
899 }
900 if (in_array($key, array('X-Content-Type-Options'))) {
901 $all[] = sprintf(' Header always set %s %s', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
902 continue;
903 }
904 if ($key == 'Strict-Transport-Security') {
905 $lines[] = sprintf(' Header set %s %s env=HTTPS', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
906 continue;
907 }
908 if ($key == 'Access-Control-Allow-Origin') {
909 $all[] = ' <IfModule mod_setenvif.c>';
910 if (is_array($value))
911 {
912 $all[] = sprintf(' SetEnvIf Origin "^(%s)$" CORS=$0', str_replace('.', '\.', join('|', $value)));
913 } else {
914 $all[] = ' SetEnvIf Origin "^(.+)$" CORS=$0';
915 }
916 $all[] = ' </IfModule>';
917 $all[] = ' Header set Access-Control-Allow-Origin %{CORS}e env=CORS';
918 continue;
919 }
920 if (in_array($key, array('Access-Control-Allow-Headers', 'Access-Control-Allow-Methods', 'Access-Control-Allow-Credentials', 'Access-Control-Max-Age', 'Access-Control-Expose-Headers'))) {
921 $all[] = sprintf(' Header set %s %s env=CORS', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
922 continue;
923 }
924 $lines[] = sprintf(' Header set %s %s', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
925 }
926 foreach ($append as $key => $value) {
927 $lines[] = sprintf(' Header append %s %s', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
928 }
929 if (!empty($lines)) {
930 $lines = array_merge(
931 array('<IfModule mod_headers.c>'),
932 $all,
933 array(' <FilesMatch "\.(php|html)$">'),
934 $lines,
935 array(' </FilesMatch>', '</IfModule>')
936 );
937 }
938 return $lines;
939 }
940
941 function apache_content_encoding_directives() {
942 $lines = array();
943 if (get_option('hh_content_encoding') == 1) {
944
945 $content_encoding_value = get_option('hh_content_encoding_value');
946 if (!$content_encoding_value) {
947 $content_encoding_value = array();
948 }
949
950 $content_encoding_ext = get_option('hh_content_encoding_ext');
951 if (!$content_encoding_ext) {
952 $content_encoding_ext = array();
953 }
954 if (!empty($content_encoding_ext)) {
955 $lines[] = sprintf('<FilesMatch "\.(%s)$">', join('|', array_keys($content_encoding_ext)));
956 $lines[] = ' <IfModule mod_deflate.c>';
957 $lines[] = ' SetOutputFilter DEFLATE';
958 $lines[] = ' </IfModule>';
959 $lines[] = '</FilesMatch>';
960 }
961 if (!empty($content_encoding_value)) {
962 if (!empty($lines)) {
963 $lines[] = '';
964 }
965 $lines[] = '<IfModule mod_deflate.c>';
966 foreach ($content_encoding_value as $item => $whatever) {
967 $lines[] = sprintf(' AddOutputFilterByType DEFLATE %s', $item);
968 }
969 $lines[] = '</IfModule>';
970 }
971 }
972
973 return $lines;
974 }
975
976 function apache_expires_directives() {
977 $lines = array();
978 if (get_option('hh_expires') == 1) {
979
980 $types = get_option('hh_expires_type', array());
981 $values = get_option('hh_expires_value', array());
982
983 $lines[] = '<IfModule mod_expires.c>';
984 $lines[] = ' ExpiresActive On';
985 foreach ($types as $type => $whatever) {
986 list($base, $period, $suffix) = explode('_', $values[$type]);
987 if (in_array($base, array('access', 'modification'))) {
988 $lines[] = $type != 'default'
989 ? sprintf(' ExpiresByType %s "%s plus %u %s"', $type, $base, $period, $suffix)
990 : sprintf(' ExpiresDefault "%s plus %u %s"', $base, $period, $suffix);
991 } elseif ($base == 'invalid') {
992 $lines[] = $type != 'default'
993 ? sprintf(' ExpiresByType %s A0', $type)
994 : sprintf(' ExpiresDefault A0');
995 }
996 }
997 $lines[] = '</IfModule>';
998 }
999
1000 return $lines;
1001 }
1002
1003 function apache_timing_directives() {
1004 $lines = array();
1005 if (get_option('hh_timing_allow_origin') == 1) {
1006 $value = get_option('hh_timing_allow_origin_value');
1007 switch ($value)
1008 {
1009 case 'origin':
1010 $value = get_option('hh_timing_allow_origin_url');
1011 break;
1012 }
1013 if (!empty($value))
1014 {
1015 $lines[] = '<IfModule mod_headers.c>';
1016 $lines[] = ' <FilesMatch "\\.(js|css|jpe?g|png|gif|eot|otf|svg|ttf|woff2?)$">';
1017 $lines[] = sprintf(' Header set Timing-Allow-Origin "%s"', $value);
1018 $lines[] = ' </FilesMatch>';
1019 $lines[] = '</IfModule>';
1020 }
1021 }
1022
1023 return $lines;
1024 }
1025
1026 function apache_auth_directives() {
1027 $lines = array();
1028 if (get_option('hh_www_authenticate') == 1) {
1029
1030 $type = get_option('hh_www_authenticate_type');
1031
1032 $file = $type == 'Basic' ? '.hh-htpasswd' : '.hh-htdigest';
1033
1034 $lines[] = '<FilesMatch "^\.hh-ht(digest|passwd)$">';
1035 $lines[] = ' Order deny,allow';
1036 $lines[] = ' Deny from all';
1037 $lines[] = '</FilesMatch>';
1038
1039 $lines[] = sprintf('<IfModule mod_auth_%s.c>', strtolower($type));
1040 $lines[] = sprintf(' AuthType %s', get_option('hh_www_authenticate_type'));
1041 $lines[] = sprintf(' AuthName "%s"', get_option('hh_www_authenticate_realm'));
1042 $lines[] = sprintf(' AuthUserFile "%s%s"', get_home_path(), $file);
1043 $lines[] = ' Require valid-user';
1044 $lines[] = '</IfModule>';
1045 }
1046
1047 return $lines;
1048 }
1049
1050 function apache_auth_credentials() {
1051 if (get_option('hh_www_authenticate') == 1) {
1052 $type = get_option('hh_www_authenticate_type');
1053 $usernames = get_option('hh_www_authenticate_user', array());
1054 $passwords = get_option('hh_www_authenticate_pswd', array());
1055 if (!is_array($usernames)) {
1056 $usernames = array($usernames);
1057 }
1058 if (!is_array($passwords)) {
1059 $passwords = array($passwords);
1060 }
1061 $realm = get_option('hh_www_authenticate_realm');
1062 $auth = array();
1063 switch ($type) {
1064 case 'Basic':
1065 $ht_file = get_home_path().'.hh-htpasswd';
1066 foreach ($usernames as $k => $user) {
1067 $auth[] = sprintf('%s:{SHA}%s', $user, base64_encode(sha1($passwords[$k], true)));
1068 }
1069 break;
1070 case 'Digest':
1071 $ht_file = get_home_path().'.hh-htdigest';
1072 foreach ($usernames as $k => $user) {
1073 $auth[] = sprintf('%s:%s:%s', $user, $realm, md5($user.':'.$realm.':'.$passwords[$k]));
1074 }
1075 break;
1076 }
1077 $auth = join("\n", $auth);
1078
1079 return compact('ht_file', 'auth');
1080 }
1081 return false;
1082 }
1083
1084 function apache_cookie_security_directives() {
1085 $lines = array();
1086 if (get_option('hh_cookie_security') == 1) {
1087 $value = get_option('hh_cookie_security_value', array());
1088 if (isset($value['HttpOnly'])) {
1089 $lines[] = 'php_flag session.cookie_httponly on';
1090 }
1091 if (isset($value['Secure'])) {
1092 $lines[] = 'php_flag session.cookie_secure on';
1093 }
1094 }
1095
1096 return $lines;
1097 }
1098
1099 function update_headers_directives() {
1100 $lines = array();
1101 if (get_option('hh_method') == 'htaccess') {
1102 $lines = apache_headers_directives();
1103 }
1104
1105 return insert_with_markers(get_home_path().'.htaccess', "HttpHeaders", $lines);
1106 }
1107
1108 function update_content_encoding_directives() {
1109 $lines = array();
1110 if (get_option('hh_method') == 'htaccess') {
1111 $lines = apache_content_encoding_directives();
1112 }
1113
1114 return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersCompression", $lines);
1115 }
1116
1117 function update_expires_directives() {
1118 $lines = array();
1119 if (get_option('hh_method') == 'htaccess') {
1120 $lines = apache_expires_directives();
1121 }
1122
1123 return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersExpires", $lines);
1124 }
1125
1126 function update_timing_directives() {
1127 $lines = array();
1128 if (get_option('hh_method') == 'htaccess') {
1129 $lines = apache_timing_directives();
1130 }
1131
1132 return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersTiming", $lines);
1133 }
1134
1135 function update_auth_directives() {
1136 $lines = array();
1137 if (get_option('hh_method') == 'htaccess') {
1138 $lines = apache_auth_directives();
1139 }
1140
1141 return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersAuth", $lines);
1142 }
1143
1144 function update_auth_credentials() {
1145 if (get_option('hh_method') == 'htaccess') {
1146 $credentials = apache_auth_credentials();
1147
1148 return @file_put_contents($credentials['ht_file'], $credentials['auth']);
1149 }
1150
1151 return false;
1152 }
1153
1154 function update_cookie_security_directives() {
1155 $lines = array();
1156 if (get_option('hh_method') == 'htaccess') {
1157 $lines = apache_cookie_security_directives();
1158 }
1159
1160 return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersCookieSecurity", $lines);
1161 }
1162
1163 function http_headers_text_domain() {
1164 load_plugin_textdomain('http-headers', false, basename( dirname( __FILE__ ) ) . '/languages/');
1165 }
1166
1167 function http_headers_settings_link( $links ) {
1168 $url = get_admin_url() . 'options-general.php?page=http-headers';
1169 $settings_link = '<a href="' . $url . '">' . __('Settings', 'http-headers') . '</a>';
1170 array_unshift( $links, $settings_link );
1171 return $links;
1172 }
1173
1174 function http_headers_after_setup_theme() {
1175 add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'http_headers_settings_link');
1176 }
1177
1178 function http_headers_enqueue($hook) {
1179 if ( 'http-headers.php' != $hook ) {
1180 # FIXME
1181 //return;
1182 }
1183
1184 wp_enqueue_script('http_headers_admin_scripts', plugin_dir_url( __FILE__ ) . 'assets/scripts.js');
1185 wp_localize_script('http_headers_admin_scripts', 'hh', array(
1186 'lbl_delete' => __('Delete', 'http-headers'),
1187 'lbl_value' => __('Value', 'http-headers'),
1188 ));
1189 wp_enqueue_style('http_headers_admin_styles', plugin_dir_url( __FILE__ ) . 'assets/styles.css');
1190 }
1191
1192 function http_headers_ajax_inspect() {
1193 check_ajax_referer('inspect');
1194 if (current_user_can('manage_options')) {
1195 include 'views/ajax-inspect.php';
1196 }
1197 wp_die();
1198 }
1199
1200 function http_headers_post_import() {
1201 check_admin_referer('import');
1202 global $wpdb;
1203 if (!(isset($_FILES['file']['tmp_name'])
1204 && is_uploaded_file($_FILES['file']['tmp_name'])
1205 && $_FILES['file']['error'] == UPLOAD_ERR_OK
1206 )) {
1207 wp_redirect(sprintf("%soptions-general.php?page=http-headers&tab=advanced&status=ERR", get_admin_url()));
1208 exit;
1209 }
1210
1211 $string = @file_get_contents($_FILES['file']['tmp_name']);
1212 if ($string === false) {
1213 wp_redirect(sprintf("%soptions-general.php?page=http-headers&tab=advanced&status=ERR", get_admin_url()));
1214 exit;
1215 }
1216
1217 $arr = preg_split('/;(\s+)?\n/', $string);
1218 foreach ($arr as $statement) {
1219 $wpdb->query($statement);
1220 }
1221
1222 wp_redirect(sprintf("%soptions-general.php?page=http-headers&tab=advanced&status=OK", get_admin_url()));
1223 exit;
1224 }
1225
1226 function http_headers_post_export() {
1227 check_admin_referer('export');
1228 global $wpdb;
1229 include 'views/includes/config.inc.php';
1230 $statement = sprintf("SELECT * FROM %s WHERE option_name IN ('%s');", $wpdb->options, join("','", $options));
1231 $results = $wpdb->get_results($statement, ARRAY_A);
1232 $sql = array();
1233 foreach ($results as $item)
1234 {
1235 $value = str_replace("'", "''", $item['option_value']);
1236 $query = array();
1237 $query[] = sprintf("INSERT INTO %s (option_id, option_name, option_value, autoload)", $wpdb->options);
1238 $query[] = sprintf("VALUES (NULL, '%s', '%s', '%s')", $item['option_name'], $value, $item['autoload']);
1239 $query[] = sprintf("ON DUPLICATE KEY UPDATE option_value = '%s', autoload = '%s';", $value, $item['autoload']);
1240 $sql[] = join("\n", $query);
1241 }
1242
1243 $sql = join("\n\n", $sql);
1244 $length = function_exists('mb_strlen') ? mb_strlen($sql) : strlen($sql);
1245 $name = sprintf('WP-HTTP-Headers-%u.sql', time());
1246
1247 # Send headers
1248 header('Pragma: public');
1249 header('Expires: 0');
1250 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
1251 header('Cache-Control: private', false);
1252 header('Content-Transfer-Encoding: binary');
1253 header('Content-Disposition: attachment; filename="'.$name.'";');
1254 header('Content-Type: application/sql');
1255 header('Content-Length: ' . $length);
1256
1257 echo $sql;
1258 exit;
1259 }
1260
1261 if ( is_admin() ){ // admin actions
1262 add_action('admin_menu', 'http_headers_admin_add_page');
1263 add_action('admin_init', 'http_headers_admin');
1264 add_action("added_option", 'http_headers_option');
1265 add_action("updated_option", 'http_headers_option');
1266 add_action('admin_enqueue_scripts', 'http_headers_enqueue');
1267 add_action('after_setup_theme', 'http_headers_after_setup_theme');
1268 add_action('plugins_loaded', 'http_headers_text_domain');
1269 add_action('wp_ajax_inspect', 'http_headers_ajax_inspect');
1270 add_action('admin_post_import', 'http_headers_post_import');
1271 add_action('admin_post_export', 'http_headers_post_export');
1272 } else {
1273 // non-admin enqueues, actions, and filters
1274 add_action('send_headers', 'http_headers');
1275 }
1276
1277 function http_headers_admin_page() {
1278 include 'views/index.php';
1279 }