Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Files that are only needed to develop or test the proxy. `export-ignore` keeps them out of
# `git archive` output and out of the source archives GitHub attaches to releases, so that a
# release download contains only the files that belong in a public web root.
#
# Note that this does NOT apply to `git clone` - a clone always contains everything, which is
# why the README documents the release archive as the way to install the proxy.
/tests export-ignore
/.github export-ignore
/.editorconfig export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/.php-version export-ignore
/composer.lock export-ignore
/phpcs.xml export-ignore
Comment thread
tzi marked this conversation as resolved.
5 changes: 5 additions & 0 deletions .github/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@
if ($isTestServer && isset($_SERVER['HTTP_X_TEST_COOKIE_ALLOWLIST_INVALID'])) {
$COOKIE_ALLOWLIST = $_SERVER['HTTP_X_TEST_COOKIE_ALLOWLIST_INVALID'];
}

// Exercise the test server's refusal to run for anything but a test configuration.
if ($isTestServer && !empty($_SERVER['HTTP_X_TEST_NON_TEST_CONFIG'])) {
$MATOMO_URL = 'https://matomo.example.org/matomo/';
}
60 changes: 44 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,40 @@ In your Matomo server:

You need to install the proxy on the server where your websites are hosted. You can do it both ways:

- download the files manually
- or install the whole repository with git
- download the source archive (recommended)
- or download the individual files manually

| :warning: Install from the archive, not with `git clone` |
|-----------------------------------------|
| A clone of this repository contains more than the proxy: it also contains the test suite, the CI configuration and other development files, none of which belong in a public web root. The source archive contains only the files the proxy needs, so use it to install. If your existing installation contains a `tests/` directory — because it was cloned, or extracted from an older archive — remove `tests/`, `.github/`, `.git/`, `vendor/` and `composer.lock` from it, or reinstall from the archive. |


| :zap: Important note about where to install the proxy |
|-----------------------------------------|
| To ensure the highest data accuracy possible, and that your Matomo cookies are set correctly, please install the proxy in your main website domain name and web server. This proxy should be ideally installed on your webserver directly under `{site_to_be_tracked}`. If you installed the proxy in a sub-domain under `analytics.{site_to_be_tracked}` then this would cause data to be less accurate. (Why? because if the sub-domain `analytics.{site_to_be_tracked}` was to resolve to a CNAME that does _not_ match `{site_to_be_tracked}` OR if it was to resolve to A/AAAA addresses that do not match the first half of the A/AAAA addresses running `{site_to_be_tracked}`, then the cookies set by the Matomo Tracker Proxy in the response would only have a lifetime of maximum 7 days on Safari >= 16.4.) |

#### Download the source archive (recommended)

Download the archive into the directory you want to serve the proxy from, for example `matomo/` in your website root directory, so that the proxy ends up at `http://{site_to_be_tracked}/matomo/matomo.php`:

```bash
cd /path/to/your/website-root
mkdir matomo
cd matomo
curl -L https://github.com/matomo-org/tracker-proxy/archive/refs/heads/master.tar.gz | tar xz --strip-components=1
cp config.php.example config.php
```

Then change the configuration in the newly created `config.php`:

- `$MATOMO_URL` should contain the URL to your Matomo server
- `$PROXY_URL` should contain the URL to the tracker-proxy server
- `$TOKEN_AUTH` should contain the `token_auth`

To update later, run the same `curl … | tar xz` command again in the same directory. Your `config.php` is not part of the archive and is therefore left untouched. Note that extracting over an existing installation only adds and overwrites files, it never deletes them: to be sure you end up with exactly the current set of files, extract into an empty directory instead and move your `config.php` over.

Be aware that with this method, `matomo.php` and other files are in a `matomo/` subdirectory. Keep that in mind when applying the instructions for the next step. Extract the archive directly into your website root directory instead if you prefer the proxy at `http://{site_to_be_tracked}/matomo.php`.

#### Manual download of `matomo.php`

- download [`matomo.php`](https://raw.githubusercontent.com/matomo-org/tracker-proxy/master/matomo.php), download [`piwik.php`](https://raw.githubusercontent.com/matomo-org/tracker-proxy/master/piwik.php), [`proxy.php`](https://raw.githubusercontent.com/matomo-org/tracker-proxy/master/proxy.php), [`matomo-proxy.php`](https://raw.githubusercontent.com/matomo-org/tracker-proxy/master/matomo-proxy.php) & if you are using the Heatmaps and Session recordings plugin also download [`plugins/HeatmapSessionRecording/configs.php`](https://raw.githubusercontent.com/matomo-org/tracker-proxy/master/plugins/HeatmapSessionRecording/configs.php)
Expand All @@ -47,19 +73,6 @@ You need to install the proxy on the server where your websites are hosted. You
- `$PROXY_URL` should contain the URL to the tracker-proxy server
- `$TOKEN_AUTH` should contain the `token_auth`

#### With git

- clone the repository: `git clone https://github.com/matomo-org/tracker-proxy.git matomo` into your website root directory (for example at `http://{site_to_be_tracked}/matomo/matomo.php`)
- copy the configuration template: `cp config.php.example config.php`
- change the configuration in the newly created `config.php`:
- `$MATOMO_URL` should contain the URL to your Matomo server
- `$PROXY_URL` should contain the URL to the tracker-proxy server
- `$TOKEN_AUTH` should contain the `token_auth`

By using git you will later be able to update by simply running `git pull`.

Be aware that with this method, `matomo.php` and other files are in a `matomo/` subdirectory. Keep that in mind when applying the instructions for the next step.

### 3. Use the proxy in the Javascript tracker

The proxy file (`http://{site_to_be_tracked}/matomo.php`) will be called by the Matomo Javascript tracker instead of calling directly the (secret) Matomo server (`http://your-matomo-domain.example.org/matomo/`).
Expand All @@ -85,7 +98,7 @@ To achieve this, change the Matomo Javascript Code that is in the footer of your
What has changed in this code snippet compared to the normal Matomo code?

- any reference(s) to the secret Matomo URL are now replaced by your website URL (the proxy).
- `matomo.js` becomes `matomo.php` (or `matomo/matomo.php` if you used the *git* method): matomo.php is the proxy script
- `matomo.js` becomes `matomo.php` (or `matomo/matomo.php` if you installed the proxy into a `matomo/` subdirectory): matomo.php is the proxy script
- make sure to replace `tracked-site-id-here` with your idsite
- if the `<noscript>` is present in your tracking code, you can remove it (it contains the secret Matomo URL which you want to hide)

Expand Down Expand Up @@ -199,6 +212,16 @@ Some tracking parameters (`cip`, `cdt`, `cdo`, `country`, `region`, `city`, `lat

If you have found a bug, you are welcome to submit a pull request.

### Working on the proxy

To work on the proxy, clone the repository:

```bash
git clone https://github.com/matomo-org/tracker-proxy.git
```

> ⚠️ **A clone is a development checkout, not an installation.** Alongside the proxy it contains the test suite and other development files, so only serve a clone from a local development web server, never from a publicly reachable web root. To install the proxy on a live site, use the [source archive](#download-the-source-archive-recommended).

### Running the tests

Before running the tests, create a config.php file w/ the following contents in the root repository directory:
Expand Down Expand Up @@ -235,6 +258,11 @@ if ($isTestServer && isset($_SERVER['HTTP_X_TEST_COOKIE_ALLOWLIST'])) {
if ($isTestServer && isset($_SERVER['HTTP_X_TEST_COOKIE_ALLOWLIST_INVALID'])) {
$COOKIE_ALLOWLIST = $_SERVER['HTTP_X_TEST_COOKIE_ALLOWLIST_INVALID'];
}

// Exercise the test server's refusal to run for anything but a test configuration.
if ($isTestServer && !empty($_SERVER['HTTP_X_TEST_NON_TEST_CONFIG'])) {
$MATOMO_URL = 'https://matomo.example.org/matomo/';
}
```

The tests need a webserver to be pointed to the root of this repository. The simplest way is to just use Vagrant:
Expand Down
13 changes: 13 additions & 0 deletions tests/ProxyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1940,6 +1940,19 @@ public function test_truthy_string_remove_visitor_ip_enables_removal()
$this->assertEquals($expected, $responseBody);
}

public function test_test_server_only_runs_for_a_test_configuration()
{
// X-Test-Non-Test-Config makes the test config point $MATOMO_URL somewhere other than
// tests/server/, which is what the test server keys its refusal on.
$response = $this->send('debug=1', null, null, ['X-Test-Non-Test-Config' => '1'], '/tests/server/matomo.php');

$responseBody = $response->getBody()->getContents();

$this->assertEquals(403, $response->getStatusCode(), $responseBody);
$this->assertStringNotContainsString('xyz', $responseBody);
$this->assertStringNotContainsString('matomo.example.org', $responseBody);
}

private function sendBulkWithoutVisitorIp($body)
{
return $this->send(
Expand Down
18 changes: 17 additions & 1 deletion tests/server/matomo.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
<?php

require_once __DIR__ . '/../../config.php';
if (file_exists(__DIR__ . '/../../config.php')) {
require_once __DIR__ . '/../../config.php';
}

// This file is a stand-in for a Matomo server, only ever meaningful together with the test
// configuration the test suite sets up. Run it only when the loaded config actually points at
// this test server, so that it stays inert in any other setup.
if (!isset($MATOMO_URL) || !is_string($MATOMO_URL) || strpos($MATOMO_URL, '/tests/server/') === false) {
header('Content-Type: text/plain; charset=utf-8');
header('X-Content-Type-Options: nosniff');
http_response_code(403);
exit("This is a test fixture. It is disabled unless \$MATOMO_URL points at tests/server/.\n");
}

if (!isset($_GET['send_image']) || $_GET['send_image'] == 1) {
header('Content-Type: image/gif');
} else {
// The request data echoed below is plain text, so say so explicitly.
header('Content-Type: text/plain; charset=utf-8');
}
header('X-Content-Type-Options: nosniff');

if (isset($_GET['status'])) {
http_response_code($_GET['status']);
Expand Down
Loading