Changeset - 02204162f917
[Not reviewed]
0 7 1
Branko Majic (branko) - 2 months ago 2024-03-06 23:02:36
branko@majic.rs
MAR-226: Added ability to override HTTP headers on incoming request to the php_website role.
8 files changed with 60 insertions and 0 deletions:
0 comments (0 inline, 0 general)
docs/releasenotes.rst
Show inline comments
 
@@ -83,12 +83,15 @@ Debian 12 Bookworm. Some minor improvements and fixes.
 
**New features/improvements**
 

	
 
* ``php_website`` role
 

	
 
  * Environment indicator can now be collapsed by clicking on the
 
    arrows on the left side.
 
  * Added parameter ``http_header_overrides`` which can be used to
 
    set/override request's HTTP headers before passing it on to the
 
    PHP application.
 

	
 
* ``mail_server`` role
 

	
 
  * Protection against forging of sender addresses has been
 
    implemented, preventing logged-in users from using arbitrary
 
    sender mail addresses, even if authenticated. Authenticated users
docs/rolereference.rst
Show inline comments
 
@@ -1658,12 +1658,37 @@ Parameters
 
**index** (string, optional, ``index.php``)
 
  Space-separated list of files which should be treated as index files by the
 
  web server. The web server will attempt opening these index files, in
 
  succession, until the first match, or until it runs out of matches, when a
 
  client requests an URI pointing to directory.
 

	
 
**http_header_overrides** (dict, optional, ``{}``)
 
  HTTP headers to set/override on the incoming request before passing
 
  it on to the PHP application. Keys are HTTP header names, values are
 
  header values.
 

	
 
  .. note::
 
     Role takes care of prefixing the headers with ``HTTP_``,
 
     converting them to upper-case, and replacing dashes with
 
     underscores - simply pass in the official HTTP header name, no
 
     extra precautions are required for PHP specifics.
 

	
 
  Double quotes in the value must be escaped with a backslash. Make
 
  sure to take into account the YAML escaping as well. For example, to
 
  set the value to ``this is quote - "``, YAML should look like one of
 
  the following:
 

	
 
  - ``this is double quote - "``
 
  - ``'this is double quote - \"'``
 
  - ``"this is double quote - \\\"'``
 

	
 
  To clear a header value, simply set its value to an empty
 
  string. Nginx variables can be used as well, however keep in mind
 
  that the dollar sign (``$``) *cannot* be used/escaped due to Nginx
 
  configuration file syntax limitations.
 

	
 
**https_tls_certificate** (string, mandatory)
 
  X.509 certificate used for TLS for HTTPS service. The file will be stored in
 
  directory ``/etc/ssl/certs/`` under name ``{{ fqdn }}_https.pem``.
 

	
 
**https_tls_key** (string, optional, mandatory)
 
  Private key used for TLS for HTTPS service. The file will be stored in
docs/usage.rst
Show inline comments
 
@@ -1414,12 +1414,16 @@ Before we start, here is a couple of useful pointers regarding the
 
  does not have a dedicated group, and instead belongs to same group
 
  as the application user.
 
* PHP applications are executed via FastCGI, using *PHP-FPM*.
 
* If you ever need to set some additional PHP FPM settings, this can
 
  easily be done via the ``additional_fpm_config`` role
 
  parameter. This particular example does not set any, though.
 
* Incoming request headers can be set/overridden using the
 
  ``http_header_overrides`` parameter. This can be useful for
 
  manipulating headers in specifics ways, such as disabling
 
  compression etc. on the application side.
 
* Mails delivered to local admin/application users are forwarded to
 
  ``root`` account (configurable via ``website_mail_recipients`` role
 
  parameter.
 
* If you ever find yourself mixing-up test and production websites,
 
  have a look at ``environment_indicator`` role parameter. It lets you
 
  insert small strip with environment information at bottom of each
roles/php_website/defaults/main.yml
Show inline comments
 
@@ -7,12 +7,13 @@ packages: []
 
php_file_regex: \.php$
 
php_rewrite_urls: []
 
rewrites: []
 
additional_fpm_config: {}
 
website_mail_recipients: "root"
 
environment_indicator: null
 
http_header_overrides: {}
 

	
 
# Internal parameters.
 
php_fpm_service_name_per_release:
 
  bullseye: "php7.4-fpm"
 
  bookworm: "php8.2-fpm"
 

	
roles/php_website/molecule/default/playbook.yml
Show inline comments
 
@@ -36,12 +36,14 @@
 
      https_tls_certificate: "{{ lookup('file', 'tests/data/x509/server/parameters-optional_https.cert.pem') }}"
 
      https_tls_key: "{{ lookup('file', 'tests/data/x509/server/parameters-optional_https.key.pem') }}"
 
      php_file_regex: "\\.myphp$"
 
      php_rewrite_urls:
 
        - ^/rewrite1/(.*)$ /rewrite.myphp?url=$1 last
 
        - ^/rewrite2/(.*)$ /rewrite.myphp?url=$1 last
 
      http_header_overrides:
 
        Accept-Encoding: 'donotencode'
 
      rewrites:
 
        - '^/rewrite_to_index1/(.*) /myindex.php last'
 
        - '^/rewrite_to_index2/(.*) /myindex.php last'
 
      packages:
 
        - "php-ldap"
 
        - "php-json"
 
@@ -92,6 +94,7 @@
 
        - myindex.myphp
 
        - path.myphp
 
        - secretfile.txt
 
        - info.myphp
 
        - 404.myphp
 
        - rewrite.myphp
 
        - headers.myphp
roles/php_website/molecule/default/tests/data/php/optional/headers.myphp
Show inline comments
 
new file 100644
 
<?php
 

	
 
foreach (getallheaders() as $name => $value) {
 
    echo "$name: $value\n";
 
}
 

	
 
?>
roles/php_website/molecule/default/tests/test_parameters_optional.py
Show inline comments
 
@@ -267,6 +267,18 @@ def test_regular_rewrites(host):
 
    assert page.stdout == open("tests/data/php/optional/myindex.php").read().rstrip()
 

	
 
    page = host.run('curl https://parameters-optional.local/rewrite_to_index2/some/path')
 

	
 
    assert page.rc == 0
 
    assert page.stdout == open("tests/data/php/optional/myindex.php").read().rstrip()
 

	
 

	
 
def test_http_header_overrides(host):
 
    """
 
    Tests if headers are overridden by Nginx prior to hitting the PHP
 
    application.
 
    """
 

	
 
    page = host.run('curl -H "Accept-Encoding: plain" https://parameters-optional.local/headers.myphp')
 

	
 
    assert page.rc == 0
 
    assert "Accept-Encoding: donotencode" in page.stdout.split("\n")
roles/php_website/templates/nginx_site.j2
Show inline comments
 
@@ -45,12 +45,17 @@ server {
 
    {% endif %}
 

	
 
    # Interpret PHP files via FastCGI.
 
    location ~ {{ php_file_regex }} {
 
        include snippets/fastcgi-php.conf;
 
        fastcgi_pass unix:/run/php/{{ fqdn }}.sock;
 

	
 
    {% for header, value in http_header_overrides | dictsort -%}
 
    fastcgi_param {{ 'HTTP_' + header.replace('-', '_').upper() }} "{{ value }}";
 
    {% endfor -%}
 

	
 
    }
 

	
 
    # Serve the files.
 
    location ~ /(.+) {
 
	try_files $uri $uri/{% if php_rewrite_urls %} @php_rewrite{% else %} =404{% endif %};
 
    }
0 comments (0 inline, 0 general)