[tor-commits] [donate/master] Added ip-address-middleware for rate limiting

peterh at torproject.org peterh at torproject.org
Wed Jun 10 22:48:37 UTC 2020


commit 723f2af78635f9e92c11b0defe9a7486f1739cf9
Author: peterh <peterh at giantrabbit.com>
Date:   Wed Jan 22 15:55:24 2020 -0800

    Added ip-address-middleware for rate limiting
    
    We need to be able to get the IP address for the request. I wanted to
    use a library so that we can handle the case where the app gets moved
    behind a proxy. Right now the ip-address-middleware is configured to
    ignore the proxy (X-Forwarded-For) addresses because client can spoof
    those, but if we do put it behind a proxy then we can trust the header
    (assuming the proxy is configured correctly) and we just need to change
    the arguments to the constructor in src/middleware.php to adjust for the
    proxy.
---
 composer.json                                      |   1 +
 composer.lock                                      | 167 +++++++++-
 vendor/akrabat/ip-address-middleware/.gitignore    |   3 +
 vendor/akrabat/ip-address-middleware/.travis.yml   |  19 ++
 vendor/akrabat/ip-address-middleware/LICENSE       |  26 ++
 vendor/akrabat/ip-address-middleware/README.md     |  62 ++++
 vendor/akrabat/ip-address-middleware/composer.json |  35 +++
 vendor/akrabat/ip-address-middleware/phpcs.xml     |  12 +
 vendor/akrabat/ip-address-middleware/phpunit.xml   |  28 ++
 .../ip-address-middleware/src/IpAddress.php        | 215 +++++++++++++
 .../ip-address-middleware/tests/IpAddressTest.php  | 342 +++++++++++++++++++++
 .../ip-address-middleware/tests/bootstrap.php      |   5 +
 vendor/composer/ClassLoader.php                    |   2 +-
 vendor/composer/autoload_psr4.php                  |   2 +
 vendor/composer/autoload_static.php                |  14 +
 vendor/composer/installed.json                     | 171 ++++++++++-
 vendor/psr/http-server-handler/LICENSE             |  21 ++
 vendor/psr/http-server-handler/README.md           |   6 +
 vendor/psr/http-server-handler/composer.json       |  36 +++
 .../src/RequestHandlerInterface.php                |  22 ++
 vendor/psr/http-server-middleware/LICENSE          |  21 ++
 vendor/psr/http-server-middleware/README.md        |   6 +
 vendor/psr/http-server-middleware/composer.json    |  36 +++
 .../src/MiddlewareInterface.php                    |  25 ++
 24 files changed, 1271 insertions(+), 6 deletions(-)

diff --git a/composer.json b/composer.json
index e4369e4e..19a361ce 100644
--- a/composer.json
+++ b/composer.json
@@ -10,6 +10,7 @@
     }
   ],
   "require": {
+    "akrabat/ip-address-middleware": "^1.0.1",
     "resque/php-resque": "^1.2.1",
     "cweagans/composer-patches": "^1.6.6",
     "monolog/monolog": "^1.22.0",
diff --git a/composer.lock b/composer.lock
index 73306b5f..20a1e815 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,9 +4,62 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "b0c77e9d10680820cb25085636638e87",
+    "content-hash": "7c1d5f5a4b44b162665e288a37eb820d",
     "packages": [
         {
+            "name": "akrabat/ip-address-middleware",
+            "version": "1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/akrabat/ip-address-middleware.git",
+                "reference": "9b0bffcad90bd365c5bfbdb430563cd4e35a93ba"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/akrabat/ip-address-middleware/zipball/9b0bffcad90bd365c5bfbdb430563cd4e35a93ba",
+                "reference": "9b0bffcad90bd365c5bfbdb430563cd4e35a93ba",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.0",
+                "psr/http-message": "^1.0",
+                "psr/http-server-middleware": "^1.0"
+            },
+            "replace": {
+                "akrabat/rka-ip-address-middleware": "*"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^6.5",
+                "squizlabs/php_codesniffer": "^3.2",
+                "zendframework/zend-diactoros": "^1.7"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "RKA\\Middleware\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Rob Allen",
+                    "email": "rob at akrabat.com",
+                    "homepage": "http://akrabat.com"
+                }
+            ],
+            "description": "PSR-15 middleware that determines the client IP address and stores it as a ServerRequest attribute",
+            "homepage": "http://github.com/akrabat/rka-ip-address-middleware",
+            "keywords": [
+                "IP",
+                "middleware",
+                "psr7"
+            ],
+            "time": "2018-07-03T06:53:57+00:00"
+        },
+        {
             "name": "colinmollenhour/credis",
             "version": "1.10.1",
             "source": {
@@ -75,6 +128,7 @@
             ],
             "description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
             "homepage": "https://github.com/container-interop/container-interop",
+            "abandoned": "psr/container",
             "time": "2017-02-14T19:40:03+00:00"
         },
         {
@@ -821,7 +875,9 @@
             },
             "type": "library",
             "extra": {
-                "patches_applied": []
+                "patches_applied": {
+                    "EXPIRE bug": "patches/predis-locale-bug.patch"
+                }
             },
             "autoload": {
                 "psr-4": {
@@ -948,6 +1004,112 @@
             "time": "2016-08-06T14:39:51+00:00"
         },
         {
+            "name": "psr/http-server-handler",
+            "version": "1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/http-server-handler.git",
+                "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/aff2f80e33b7f026ec96bb42f63242dc50ffcae7",
+                "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.0",
+                "psr/http-message": "^1.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Http\\Server\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for HTTP server-side request handler",
+            "keywords": [
+                "handler",
+                "http",
+                "http-interop",
+                "psr",
+                "psr-15",
+                "psr-7",
+                "request",
+                "response",
+                "server"
+            ],
+            "time": "2018-10-30T16:46:14+00:00"
+        },
+        {
+            "name": "psr/http-server-middleware",
+            "version": "1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/http-server-middleware.git",
+                "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/2296f45510945530b9dceb8bcedb5cb84d40c5f5",
+                "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.0",
+                "psr/http-message": "^1.0",
+                "psr/http-server-handler": "^1.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Http\\Server\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for HTTP server-side middleware",
+            "keywords": [
+                "http",
+                "http-interop",
+                "middleware",
+                "psr",
+                "psr-15",
+                "psr-7",
+                "request",
+                "response"
+            ],
+            "time": "2018-10-30T17:12:04+00:00"
+        },
+        {
             "name": "psr/log",
             "version": "1.1.0",
             "source": {
@@ -2328,7 +2490,6 @@
                 "mock",
                 "xunit"
             ],
-            "abandoned": true,
             "time": "2017-06-30T09:13:00+00:00"
         },
         {
diff --git a/vendor/akrabat/ip-address-middleware/.gitignore b/vendor/akrabat/ip-address-middleware/.gitignore
new file mode 100644
index 00000000..05ab16b8
--- /dev/null
+++ b/vendor/akrabat/ip-address-middleware/.gitignore
@@ -0,0 +1,3 @@
+build
+vendor
+composer.lock
diff --git a/vendor/akrabat/ip-address-middleware/.travis.yml b/vendor/akrabat/ip-address-middleware/.travis.yml
new file mode 100644
index 00000000..3b724225
--- /dev/null
+++ b/vendor/akrabat/ip-address-middleware/.travis.yml
@@ -0,0 +1,19 @@
+sudo: false
+
+language: php
+
+php:
+  - 7.0
+  - 7.1
+  - 7.2
+
+before_install:
+  - composer self-update
+
+install:
+  - travis_retry composer install --no-interaction
+  - composer info -i
+
+script:
+  - vendor/bin/phpcs
+  - vendor/bin/phpunit
diff --git a/vendor/akrabat/ip-address-middleware/LICENSE b/vendor/akrabat/ip-address-middleware/LICENSE
new file mode 100644
index 00000000..1f8a2655
--- /dev/null
+++ b/vendor/akrabat/ip-address-middleware/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) 2015, Rob Allen (rob at akrabat.com)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    * The name of Rob Allen may not be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/akrabat/ip-address-middleware/README.md b/vendor/akrabat/ip-address-middleware/README.md
new file mode 100644
index 00000000..da2c8bc9
--- /dev/null
+++ b/vendor/akrabat/ip-address-middleware/README.md
@@ -0,0 +1,62 @@
+# Client IP address middleware
+
+PSR-15 Middleware that determines the client IP address and stores it as an `ServerRequest` attribute called `ip_address`. It optionally checks various common proxy headers and then falls back to `$_SERVER['REMOTE_ADDR']`.
+
+[![Build status][Master image]][Master]
+
+
+## Configuration
+
+The constructor takes 4 parameters which can be used to configure this middleware.
+
+**Check proxy headers**
+
+Note that the proxy headers are only checked if the first parameter to the constructor is set to `true`. If set to false, then only `$_SERVER['REMOTE_ADDR']` is used.
+
+**Trusted Proxies**
+
+If you configure to check the proxy headers (first parameter is `true`), you have to provide an array of trusted proxies as the second parameter. If the array is empty, the proxy headers will always be evaluated. If the array is not empty, it must contain strings with IP addresses, one of them must be the `$_SERVER['REMOTE_ADDR']` variable in order to allow evaluating the proxy headers - otherwise the `REMOTE_ADDR` itself is returned.
+
+**Attribute name**
+
+By default, the name of the attribute is '`ip_address`'. This can be changed by the third constructor parameter.
+
+**Headers to inspect**
+
+By default, this middleware checks the 'Forwarded', 'X-Forwarded-For', 'X-Forwarded', 'X-Cluster-Client-Ip' and 'Client-Ip' headers. You can replace this list with your own using the fourth constructor parameter.
+
+## Security considerations
+
+A malicious client may send any header to your proxy, including any proxy headers, containing any IP address. If your proxy simply adds another IP address to the header, an attacker can send a fake IP. Make sure to setup your proxy in a way that removes any sent (and possibly faked) headers from the original request and replaces them with correct values (i.e. the currently used `REMOTE_ADDR` on the proxy server).
+
+This library cannot by design ensure you get correct and trustworthy results if your network environment isn't setup properly.
+
+## Installation
+
+`composer require akrabat/ip-address-middleware`
+
+## Usage
+
+In Slim 3:
+
+```php
+$checkProxyHeaders = true; // Note: Never trust the IP address for security processes!
+$trustedProxies = ['10.0.0.1', '10.0.0.2']; // Note: Never trust the IP address for security processes!
+$app->add(new RKA\Middleware\IpAddress($checkProxyHeaders, $trustedProxies));
+
+$app->get('/', function ($request, $response, $args) {
+    $ipAddress = $request->getAttribute('ip_address');
+
+    return $response;
+});
+```
+
+## Testing
+
+* Code style: ``$ vendor/bin/phpcs``
+* Unit tests: ``$ vendor/bin/phpunit``
+* Code coverage: ``$ vendor/bin/phpunit --coverage-html ./build``
+
+
+[Master]: https://travis-ci.org/akrabat/ip-address-middleware
+[Master image]: https://secure.travis-ci.org/akrabat/ip-address-middleware.svg?branch=master
diff --git a/vendor/akrabat/ip-address-middleware/composer.json b/vendor/akrabat/ip-address-middleware/composer.json
new file mode 100644
index 00000000..984ee440
--- /dev/null
+++ b/vendor/akrabat/ip-address-middleware/composer.json
@@ -0,0 +1,35 @@
+{
+    "name": "akrabat/ip-address-middleware",
+    "description": "PSR-15 middleware that determines the client IP address and stores it as a ServerRequest attribute",
+    "keywords": [
+        "psr7", "middleware", "ip"
+    ],
+    "homepage": "http://github.com/akrabat/rka-ip-address-middleware",
+    "type": "library",
+    "license": "BSD-3-Clause",
+    "authors": [
+        {
+            "name": "Rob Allen",
+            "email": "rob at akrabat.com",
+            "homepage": "http://akrabat.com"
+        }
+    ],
+    "replace": {
+        "akrabat/rka-ip-address-middleware": "*"
+    },
+    "require": {
+        "php": "^7.0",
+        "psr/http-message": "^1.0",
+        "psr/http-server-middleware": "^1.0"
+    },
+    "require-dev": {
+        "phpunit/phpunit": "^6.5",
+        "squizlabs/php_codesniffer": "^3.2",
+        "zendframework/zend-diactoros": "^1.7"
+    },
+    "autoload": {
+        "psr-4": {
+            "RKA\\Middleware\\": "src"
+        }
+    }
+}
diff --git a/vendor/akrabat/ip-address-middleware/phpcs.xml b/vendor/akrabat/ip-address-middleware/phpcs.xml
new file mode 100644
index 00000000..7c60e0a5
--- /dev/null
+++ b/vendor/akrabat/ip-address-middleware/phpcs.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<ruleset name="RKA">
+    <rule ref="PSR2"/>
+
+    <arg value="p" />
+    <arg name="colors"/>
+
+    <!-- Check src and tests directories -->
+    <file>src</file>
+    <file>tests</file>
+
+</ruleset>
diff --git a/vendor/akrabat/ip-address-middleware/phpunit.xml b/vendor/akrabat/ip-address-middleware/phpunit.xml
new file mode 100644
index 00000000..fb5fbdc1
--- /dev/null
+++ b/vendor/akrabat/ip-address-middleware/phpunit.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.7/phpunit.xsd"
+         backupGlobals="false"
+         backupStaticAttributes="false"
+         beStrictAboutTestsThatDoNotTestAnything="true"
+         beStrictAboutChangesToGlobalState="true"
+         beStrictAboutOutputDuringTests="true"
+         colors="true"
+         convertErrorsToExceptions="true"
+         convertNoticesToExceptions="true"
+         convertWarningsToExceptions="true"
+         processIsolation="false"
+         stopOnFailure="false"
+         bootstrap="tests/bootstrap.php"
+>
+    <testsuites>
+        <testsuite name="Test Suite">
+            <directory>./tests/</directory>
+        </testsuite>
+    </testsuites>
+    <filter>
+        <whitelist processUncoveredFilesFromWhitelist="true">
+            <directory suffix=".php">./src</directory>
+        </whitelist>
+    </filter>
+</phpunit>
\ No newline at end of file
diff --git a/vendor/akrabat/ip-address-middleware/src/IpAddress.php b/vendor/akrabat/ip-address-middleware/src/IpAddress.php
new file mode 100644
index 00000000..c277a879
--- /dev/null
+++ b/vendor/akrabat/ip-address-middleware/src/IpAddress.php
@@ -0,0 +1,215 @@
+<?php
+namespace RKA\Middleware;
+
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+class IpAddress implements MiddlewareInterface
+{
+    /**
+     * Enable checking of proxy headers (X-Forwarded-For to determined client IP.
+     *
+     * Defaults to false as only $_SERVER['REMOTE_ADDR'] is a trustworthy source
+     * of IP address.
+     *
+     * @var bool
+     */
+    protected $checkProxyHeaders;
+
+    /**
+     * List of trusted proxy IP addresses
+     *
+     * If not empty, then one of these IP addresses must be in $_SERVER['REMOTE_ADDR']
+     * in order for the proxy headers to be looked at.
+     *
+     * @var array
+     */
+    protected $trustedProxies;
+
+    /**
+     * Name of the attribute added to the ServerRequest object
+     *
+     * @var string
+     */
+    protected $attributeName = 'ip_address';
+
+    /**
+     * List of proxy headers inspected for the client IP address
+     *
+     * @var array
+     */
+    protected $headersToInspect = [
+        'Forwarded',
+        'X-Forwarded-For',
+        'X-Forwarded',
+        'X-Cluster-Client-Ip',
+        'Client-Ip',
+    ];
+
+    /**
+     * Constructor
+     *
+     * @param bool $checkProxyHeaders Whether to use proxy headers to determine client IP
+     * @param array $trustedProxies   List of IP addresses of trusted proxies
+     * @param string $attributeName   Name of attribute added to ServerRequest object
+     * @param array $headersToInspect List of headers to inspect
+     */
+    public function __construct(
+        $checkProxyHeaders = false,
+        array $trustedProxies = null,
+        $attributeName = null,
+        array $headersToInspect = []
+    ) {
+        if ($checkProxyHeaders && $trustedProxies === null) {
+            throw new \InvalidArgumentException('Use of the forward headers requires an array for trusted proxies.');
+        }
+
+        $this->checkProxyHeaders = $checkProxyHeaders;
+        $this->trustedProxies = $trustedProxies;
+
+        if ($attributeName) {
+            $this->attributeName = $attributeName;
+        }
+        if (!empty($headersToInspect)) {
+            $this->headersToInspect = $headersToInspect;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Set the "$attributeName" attribute to the client's IP address as determined from
+     * the proxy header (X-Forwarded-For or from $_SERVER['REMOTE_ADDR']
+     */
+    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
+    {
+        $ipAddress = $this->determineClientIpAddress($request);
+        $request = $request->withAttribute($this->attributeName, $ipAddress);
+
+        return $handler->handle($request);
+    }
+
+    /**
+     * Set the "$attributeName" attribute to the client's IP address as determined from
+     * the proxy header (X-Forwarded-For or from $_SERVER['REMOTE_ADDR']
+     *
+     * @param ServerRequestInterface $request PSR7 request
+     * @param ResponseInterface $response     PSR7 response
+     * @param callable $next                  Next middleware
+     *
+     * @return ResponseInterface
+     */
+    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next)
+    {
+        if (!$next) {
+            return $response;
+        }
+
+        $ipAddress = $this->determineClientIpAddress($request);
+        $request = $request->withAttribute($this->attributeName, $ipAddress);
+
+        return $response = $next($request, $response);
+    }
+
+    /**
+     * Find out the client's IP address from the headers available to us
+     *
+     * @param  ServerRequestInterface $request PSR-7 Request
+     * @return string
+     */
+    protected function determineClientIpAddress($request)
+    {
+        $ipAddress = null;
+
+        $serverParams = $request->getServerParams();
+        if (isset($serverParams['REMOTE_ADDR'])) {
+            $remoteAddr = $this->extractIpAddress($serverParams['REMOTE_ADDR']);
+            if ($this->isValidIpAddress($remoteAddr)) {
+                $ipAddress = $remoteAddr;
+            }
+        }
+
+        $checkProxyHeaders = $this->checkProxyHeaders;
+        if ($checkProxyHeaders && !empty($this->trustedProxies)) {
+            if (!in_array($ipAddress, $this->trustedProxies)) {
+                $checkProxyHeaders = false;
+            }
+        }
+
+        if ($checkProxyHeaders) {
+            foreach ($this->headersToInspect as $header) {
+                if ($request->hasHeader($header)) {
+                    $ip = $this->getFirstIpAddressFromHeader($request, $header);
+                    if ($this->isValidIpAddress($ip)) {
+                        $ipAddress = $ip;
+                        break;
+                    }
+                }
+            }
+        }
+
+        return $ipAddress;
+    }
+
+    /**
+     * Remove port from IPV4 address if it exists
+     *
+     * Note: leaves IPV6 addresses alone
+     *
+     * @param  string $ipAddress
+     * @return string
+     */
+    protected function extractIpAddress($ipAddress)
+    {
+        $parts = explode(':', $ipAddress);
+        if (count($parts) == 2) {
+            if (filter_var($parts[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false) {
+                return $parts[0];
+            }
+        }
+
+        return $ipAddress;
+    }
+
+    /**
+     * Check that a given string is a valid IP address
+     *
+     * @param  string  $ip
+     * @return boolean
+     */
+    protected function isValidIpAddress($ip)
+    {
+        $flags = FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6;
+        if (filter_var($ip, FILTER_VALIDATE_IP, $flags) === false) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Find out the client's IP address from the headers available to us
+     *
+     * @param  ServerRequestInterface $request PSR-7 Request
+     * @param  string $header Header name
+     * @return string
+     */
+    private function getFirstIpAddressFromHeader($request, $header)
+    {
+        $items = explode(',', $request->getHeaderLine($header));
+        $headerValue = trim(reset($items));
+
+        if (ucfirst($header) == 'Forwarded') {
+            foreach (explode(';', $headerValue) as $headerPart) {
+                if (strtolower(substr($headerPart, 0, 4)) == 'for=') {
+                    $for = explode(']', $headerPart);
+                    $headerValue = trim(substr(reset($for), 4), " \t\n\r\0\x0B" . "\"[]");
+                    break;
+                }
+            }
+        }
+
+        return $this->extractIpAddress($headerValue);
+    }
+}
diff --git a/vendor/akrabat/ip-address-middleware/tests/IpAddressTest.php b/vendor/akrabat/ip-address-middleware/tests/IpAddressTest.php
new file mode 100644
index 00000000..d7b09d58
--- /dev/null
+++ b/vendor/akrabat/ip-address-middleware/tests/IpAddressTest.php
@@ -0,0 +1,342 @@
+<?php
+namespace RKA\Middleware\Test;
+
+use PHPUnit\Framework\TestCase;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use RKA\Middleware\IpAddress;
+use RuntimeException;
+use Zend\Diactoros\Response;
+use Zend\Diactoros\ServerRequest;
+use Zend\Diactoros\ServerRequestFactory;
+use Zend\Diactoros\Stream;
+use Zend\Diactoros\Uri;
+
+class RendererTest extends TestCase
+{
+    public function testIpSetByRemoteAddr()
+    {
+        $middleware = new IPAddress(false, [], 'IP');
+
+        $request = ServerRequestFactory::fromGlobals([
+            'REMOTE_ADDR' => '192.168.1.1',
+        ]);
+        $response = new Response();
+
+        $response  = $middleware($request, $response, function ($request, $response) use (&$ipAddress) {
+            // simply store the "ip_address" attribute in to the referenced $ipAddress
+            $ipAddress = $request->getAttribute('IP');
+            return $response;
+        });
+
+        $this->assertSame('192.168.1.1', $ipAddress);
+    }
+
+    public function testIpWithPortSetByRemoteAddr()
+    {
+        $middleware = new IPAddress(false, [], 'IP');
+
+        $request = ServerRequestFactory::fromGlobals([
+            'REMOTE_ADDR' => '192.168.1.1:80',
+        ]);
+        $response = new Response();
+
+        $response  = $middleware($request, $response, function ($request, $response) use (&$ipAddress) {
+            // simply store the "ip_address" attribute in to the referenced $ipAddress
+            $ipAddress = $request->getAttribute('IP');
+            return $response;
+        });
+
+        $this->assertSame('192.168.1.1', $ipAddress);
+    }
+
+    public function testIpIsNullIfMissing()
+    {
+        $middleware = new IPAddress();
+
+        $request = ServerRequestFactory::fromGlobals();
+        $response = new Response();
+
+        $ipAddress = '123';
+        $response  = $middleware($request, $response, function ($request, $response) use (&$ipAddress) {
+            // simply store the "ip_address" attribute in to the referenced $ipAddress
+            $ipAddress = $request->getAttribute('ip_address');
+            return $response;
+        });
+
+        $this->assertNull($ipAddress);
+    }
+
+    public function testXForwardedForIp()
+    {
+        $middleware = new IPAddress(true, []);
+
+        $request = ServerRequestFactory::fromGlobals([
+            'REMOTE_ADDR' => '192.168.1.1',
+            'HTTP_X_FORWARDED_FOR' => '192.168.1.3, 192.168.1.2, 192.168.1.1'
+        ]);
+        $response = new Response();
+
+        $ipAddress = '123';
+        $response  = $middleware($request, $response, function ($request, $response) use (&$ipAddress) {
+            // simply store the "ip_address" attribute in to the referenced $ipAddress
+            $ipAddress = $request->getAttribute('ip_address');
+            return $response;
+        });
+
+        $this->assertSame('192.168.1.3', $ipAddress);
+    }
+
+    public function testXForwardedForIpWithPort()
+    {
+        $middleware = new IPAddress(true, ['192.168.1.1']);
+
+        $request = ServerRequestFactory::fromGlobals([
+            'REMOTE_ADDR' => '192.168.1.1:81',
+            'HTTP_X_FORWARDED_FOR' => '192.168.1.3:81, 192.168.1.2:81, 192.168.1.1:81'
+        ]);
+        $response = new Response();
+
+        $ipAddress = '123';
+        $response  = $middleware($request, $response, function ($request, $response) use (&$ipAddress) {
+            // simply store the "ip_address" attribute in to the referenced $ipAddress
+            $ipAddress = $request->getAttribute('ip_address');
+            return $response;
+        });
+
+        $this->assertSame('192.168.1.3', $ipAddress);
+    }
+
+    public function testProxyIpIsIgnored()
+    {
+        $middleware = new IPAddress();
+
+        $request = ServerRequestFactory::fromGlobals([
+            'REMOTE_ADDR' => '192.168.0.1',
+            'HTTP_X_FORWARDED_FOR' => '192.168.1.3, 192.168.1.2, 192.168.1.1'
+        ]);
+        $response = new Response();
+
+        $ipAddress = '123';
+        $response  = $middleware($request, $response, function ($request, $response) use (&$ipAddress) {
+            // simply store the "ip_address" attribute in to the referenced $ipAddress
+            $ipAddress = $request->getAttribute('ip_address');
+            return $response;
+        });
+
+        $this->assertSame('192.168.0.1', $ipAddress);
+    }
+
+    public function testHttpClientIp()
+    {
+        $middleware = new IPAddress(true, []);
+
+        $request = ServerRequestFactory::fromGlobals([
+            'REMOTE_ADDR' => '192.168.1.1',
+            'HTTP_CLIENT_IP' => '192.168.1.3'
+        ]);
+        $response = new Response();
+
+        $ipAddress = '123';
+        $response  = $middleware($request, $response, function ($request, $response) use (&$ipAddress) {
+            // simply store the "ip_address" attribute in to the referenced $ipAddress
+            $ipAddress = $request->getAttribute('ip_address');
+            return $response;
+        });
+
+        $this->assertSame('192.168.1.3', $ipAddress);
+    }
+
+    public function testXForwardedForIpV6()
+    {
+        $middleware = new IPAddress(true, []);
+
+        $request = ServerRequestFactory::fromGlobals([
+            'REMOTE_ADDR' => '192.168.1.1',
+            'HTTP_X_FORWARDED_FOR' => '001:DB8::21f:5bff:febf:ce22:8a2e'
+        ]);
+        $response = new Response();
+
+        $ipAddress = '123';
+        $response  = $middleware($request, $response, function ($request, $response) use (&$ipAddress) {
+            // simply store the "ip_address" attribute in to the referenced $ipAddress
+            $ipAddress = $request->getAttribute('ip_address');
+            return $response;
+        });
+
+        $this->assertSame('001:DB8::21f:5bff:febf:ce22:8a2e', $ipAddress);
+    }
+
+    public function testXForwardedForWithInvalidIp()
+    {
+        $middleware = new IPAddress(true, []);
+
+        $request = ServerRequestFactory::fromGlobals([
+            'REMOTE_ADDR' => '192.168.1.1',
+            'HTTP_X_FORWARDED_FOR' => 'foo-bar'
+        ]);
+        $response = new Response();
+
+        $ipAddress = '123';
+        $response  = $middleware($request, $response, function ($request, $response) use (&$ipAddress) {
+            // simply store the "ip_address" attribute in to the referenced $ipAddress
+            $ipAddress = $request->getAttribute('ip_address');
+            return $response;
+        });
+
+        $this->assertSame('192.168.1.1', $ipAddress);
+    }
+
+    public function testXForwardedForIpWithTrustedProxy()
+    {
+        $middleware = new IPAddress(true, ['192.168.0.1', '192.168.0.2']);
+
+        $request = ServerRequestFactory::fromGlobals([
+            'REMOTE_ADDR' => '192.168.0.2',
+            'HTTP_X_FORWARDED_FOR' => '192.168.1.3, 192.168.1.2, 192.168.1.1'
+        ]);
+        $response = new Response();
+
+        $ipAddress = '123';
+        $response  = $middleware($request, $response, function ($request, $response) use (&$ipAddress) {
+            // simply store the "ip_address" attribute in to the referenced $ipAddress
+            $ipAddress = $request->getAttribute('ip_address');
+            return $response;
+        });
+
+        $this->assertSame('192.168.1.3', $ipAddress);
+    }
+
+    public function testXForwardedForIpWithUntrustedProxy()
+    {
+        $middleware = new IPAddress(true, ['192.168.0.1']);
+
+        $request = ServerRequestFactory::fromGlobals([
+            'REMOTE_ADDR' => '192.168.0.2',
+            'HTTP_X_FORWARDED_FOR' => '192.168.1.3, 192.168.1.2, 192.168.1.1'
+        ]);
+        $response = new Response();
+
+        $ipAddress = '123';
+        $response  = $middleware($request, $response, function ($request, $response) use (&$ipAddress) {
+            // simply store the "ip_address" attribute in to the referenced $ipAddress
+            $ipAddress = $request->getAttribute('ip_address');
+            return $response;
+        });
+
+        $this->assertSame('192.168.0.2', $ipAddress);
+    }
+
+    public function testForwardedWithMultipleFor()
+    {
+        $middleware = new IPAddress(true, []);
+
+        $request = ServerRequestFactory::fromGlobals([
+            'REMOTE_ADDR' => '192.168.1.1',
+            'HTTP_FORWARDED' => 'for=192.0.2.43, for=198.51.100.17;by=203.0.113.60;proto=http;host=example.com',
+        ]);
+        $response = new Response();
+
+        $ipAddress = '123';
+        $response  = $middleware($request, $response, function ($request, $response) use (&$ipAddress) {
+            // simply store the "ip_address" attribute in to the referenced $ipAddress
+            $ipAddress = $request->getAttribute('ip_address');
+            return $response;
+        });
+
+        $this->assertSame('192.0.2.43', $ipAddress);
+    }
+
+    public function testForwardedWithAllOptions()
+    {
+        $middleware = new IPAddress(true, []);
+
+        $request = ServerRequestFactory::fromGlobals([
+            'REMOTE_ADDR' => '192.168.1.1',
+            'HTTP_FORWARDED' => 'for=192.0.2.60; proto=http;by=203.0.113.43; host=_hiddenProxy, for=192.0.2.61',
+        ]);
+        $response = new Response();
+
+        $ipAddress = '123';
+        $response  = $middleware($request, $response, function ($request, $response) use (&$ipAddress) {
+            // simply store the "ip_address" attribute in to the referenced $ipAddress
+            $ipAddress = $request->getAttribute('ip_address');
+            return $response;
+        });
+
+        $this->assertSame('192.0.2.60', $ipAddress);
+    }
+
+    public function testForwardedWithWithIpV6()
+    {
+        $middleware = new IPAddress(true, []);
+
+        $request = ServerRequestFactory::fromGlobals([
+            'REMOTE_ADDR' => '192.168.1.1',
+            'HTTP_FORWARDED' => 'For="[2001:db8:cafe::17]:4711", for=_internalProxy',
+        ]);
+        $response = new Response();
+
+        $ipAddress = '123';
+        $response  = $middleware($request, $response, function ($request, $response) use (&$ipAddress) {
+            // simply store the "ip_address" attribute in to the referenced $ipAddress
+            $ipAddress = $request->getAttribute('ip_address');
+            return $response;
+        });
+
+        $this->assertSame('2001:db8:cafe::17', $ipAddress);
+    }
+
+    public function testCustomHeader()
+    {
+        $headersToInspect = [
+            'Foo-Bar'
+        ];
+        $middleware = new IPAddress(true, [], null, $headersToInspect);
+
+        $request = ServerRequestFactory::fromGlobals([
+            'REMOTE_ADDR' => '192.168.0.1',
+        ]);
+        $request = $request->withAddedHeader('Foo-Bar', '192.168.1.3');
+        $response = new Response();
+
+        $ipAddress = '123';
+        $response  = $middleware($request, $response, function ($request, $response) use (&$ipAddress) {
+            // simply store the "ip_address" attribute in to the referenced $ipAddress
+            $ipAddress = $request->getAttribute('ip_address');
+            return $response;
+        });
+
+        $this->assertSame('192.168.1.3', $ipAddress);
+    }
+
+
+    public function testPSR15()
+    {
+        $middleware = new IPAddress();
+        $request = ServerRequestFactory::fromGlobals([
+            'REMOTE_ADDR' => '192.168.0.1',
+        ]);
+
+        $handler = (new class implements RequestHandlerInterface {
+            public function handle(ServerRequestInterface $request): ResponseInterface
+            {
+                $response = new Response();
+                $response->getBody()->write("Hello World");
+
+                return $response;
+            }
+        });
+        $response = $middleware->process($request, $handler);
+
+        $this->assertSame("Hello World", (string) $response->getBody());
+    }
+
+    public function testNotGivingAProxyListShouldThrowException()
+    {
+        $this->expectException(\InvalidArgumentException::class);
+        new IpAddress(true);
+    }
+}
diff --git a/vendor/akrabat/ip-address-middleware/tests/bootstrap.php b/vendor/akrabat/ip-address-middleware/tests/bootstrap.php
new file mode 100644
index 00000000..a4ae4bea
--- /dev/null
+++ b/vendor/akrabat/ip-address-middleware/tests/bootstrap.php
@@ -0,0 +1,5 @@
+<?php
+
+// Enable Composer autoloader
+$autoloader = require dirname(__DIR__) . '/vendor/autoload.php';
+$autoloader->addPsr4('RKA\\Middleware\\Test\\', __DIR__);
diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php
index 95f7e097..fce8549f 100644
--- a/vendor/composer/ClassLoader.php
+++ b/vendor/composer/ClassLoader.php
@@ -279,7 +279,7 @@ class ClassLoader
      */
     public function setApcuPrefix($apcuPrefix)
     {
-        $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
+        $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
     }
 
     /**
diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php
index df78f4a3..66d00c24 100644
--- a/vendor/composer/autoload_psr4.php
+++ b/vendor/composer/autoload_psr4.php
@@ -21,7 +21,9 @@ return array(
     'Stripe\\' => array($vendorDir . '/stripe/stripe-php/lib'),
     'Slim\\Views\\' => array($vendorDir . '/slim/twig-view/src'),
     'Slim\\' => array($vendorDir . '/slim/slim/Slim'),
+    'RKA\\Middleware\\' => array($vendorDir . '/akrabat/ip-address-middleware/src'),
     'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
+    'Psr\\Http\\Server\\' => array($vendorDir . '/psr/http-server-handler/src', $vendorDir . '/psr/http-server-middleware/src'),
     'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
     'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
     'Prophecy\\' => array($vendorDir . '/phpspec/prophecy/src/Prophecy'),
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
index 3bb196bf..26492f4f 100644
--- a/vendor/composer/autoload_static.php
+++ b/vendor/composer/autoload_static.php
@@ -49,9 +49,14 @@ class ComposerStaticInit03db25c8965eb7fcdca0d6c90029b515
             'Slim\\Views\\' => 11,
             'Slim\\' => 5,
         ),
+        'R' => 
+        array (
+            'RKA\\Middleware\\' => 15,
+        ),
         'P' => 
         array (
             'Psr\\Log\\' => 8,
+            'Psr\\Http\\Server\\' => 16,
             'Psr\\Http\\Message\\' => 17,
             'Psr\\Container\\' => 14,
             'Prophecy\\' => 9,
@@ -145,10 +150,19 @@ class ComposerStaticInit03db25c8965eb7fcdca0d6c90029b515
         array (
             0 => __DIR__ . '/..' . '/slim/slim/Slim',
         ),
+        'RKA\\Middleware\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/akrabat/ip-address-middleware/src',
+        ),
         'Psr\\Log\\' => 
         array (
             0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
         ),
+        'Psr\\Http\\Server\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/psr/http-server-handler/src',
+            1 => __DIR__ . '/..' . '/psr/http-server-middleware/src',
+        ),
         'Psr\\Http\\Message\\' => 
         array (
             0 => __DIR__ . '/..' . '/psr/http-message/src',
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index b9d32b23..3bb5fe6b 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -1,5 +1,60 @@
 [
     {
+        "name": "akrabat/ip-address-middleware",
+        "version": "1.0.1",
+        "version_normalized": "1.0.1.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/akrabat/ip-address-middleware.git",
+            "reference": "9b0bffcad90bd365c5bfbdb430563cd4e35a93ba"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/akrabat/ip-address-middleware/zipball/9b0bffcad90bd365c5bfbdb430563cd4e35a93ba",
+            "reference": "9b0bffcad90bd365c5bfbdb430563cd4e35a93ba",
+            "shasum": ""
+        },
+        "require": {
+            "php": "^7.0",
+            "psr/http-message": "^1.0",
+            "psr/http-server-middleware": "^1.0"
+        },
+        "replace": {
+            "akrabat/rka-ip-address-middleware": "*"
+        },
+        "require-dev": {
+            "phpunit/phpunit": "^6.5",
+            "squizlabs/php_codesniffer": "^3.2",
+            "zendframework/zend-diactoros": "^1.7"
+        },
+        "time": "2018-07-03T06:53:57+00:00",
+        "type": "library",
+        "installation-source": "dist",
+        "autoload": {
+            "psr-4": {
+                "RKA\\Middleware\\": "src"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "BSD-3-Clause"
+        ],
+        "authors": [
+            {
+                "name": "Rob Allen",
+                "email": "rob at akrabat.com",
+                "homepage": "http://akrabat.com"
+            }
+        ],
+        "description": "PSR-15 middleware that determines the client IP address and stores it as a ServerRequest attribute",
+        "homepage": "http://github.com/akrabat/rka-ip-address-middleware",
+        "keywords": [
+            "IP",
+            "middleware",
+            "psr7"
+        ]
+    },
+    {
         "name": "colinmollenhour/credis",
         "version": "1.10.1",
         "version_normalized": "1.10.1.0",
@@ -72,7 +127,8 @@
             "MIT"
         ],
         "description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
-        "homepage": "https://github.com/container-interop/container-interop"
+        "homepage": "https://github.com/container-interop/container-interop",
+        "abandoned": "psr/container"
     },
     {
         "name": "cweagans/composer-patches",
@@ -1499,7 +1555,8 @@
         "keywords": [
             "mock",
             "xunit"
-        ]
+        ],
+        "abandoned": true
     },
     {
         "name": "pimple/pimple",
@@ -1714,6 +1771,116 @@
         ]
     },
     {
+        "name": "psr/http-server-handler",
+        "version": "1.0.1",
+        "version_normalized": "1.0.1.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/php-fig/http-server-handler.git",
+            "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/aff2f80e33b7f026ec96bb42f63242dc50ffcae7",
+            "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=7.0",
+            "psr/http-message": "^1.0"
+        },
+        "time": "2018-10-30T16:46:14+00:00",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "1.0.x-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-4": {
+                "Psr\\Http\\Server\\": "src/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "PHP-FIG",
+                "homepage": "http://www.php-fig.org/"
+            }
+        ],
+        "description": "Common interface for HTTP server-side request handler",
+        "keywords": [
+            "handler",
+            "http",
+            "http-interop",
+            "psr",
+            "psr-15",
+            "psr-7",
+            "request",
+            "response",
+            "server"
+        ]
+    },
+    {
+        "name": "psr/http-server-middleware",
+        "version": "1.0.1",
+        "version_normalized": "1.0.1.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/php-fig/http-server-middleware.git",
+            "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/2296f45510945530b9dceb8bcedb5cb84d40c5f5",
+            "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=7.0",
+            "psr/http-message": "^1.0",
+            "psr/http-server-handler": "^1.0"
+        },
+        "time": "2018-10-30T17:12:04+00:00",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "1.0.x-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-4": {
+                "Psr\\Http\\Server\\": "src/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "PHP-FIG",
+                "homepage": "http://www.php-fig.org/"
+            }
+        ],
+        "description": "Common interface for HTTP server-side middleware",
+        "keywords": [
+            "http",
+            "http-interop",
+            "middleware",
+            "psr",
+            "psr-15",
+            "psr-7",
+            "request",
+            "response"
+        ]
+    },
+    {
         "name": "psr/log",
         "version": "1.1.0",
         "version_normalized": "1.1.0.0",
diff --git a/vendor/psr/http-server-handler/LICENSE b/vendor/psr/http-server-handler/LICENSE
new file mode 100644
index 00000000..b71ec5df
--- /dev/null
+++ b/vendor/psr/http-server-handler/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 PHP Framework Interoperability Group
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/psr/http-server-handler/README.md b/vendor/psr/http-server-handler/README.md
new file mode 100644
index 00000000..1b7b4860
--- /dev/null
+++ b/vendor/psr/http-server-handler/README.md
@@ -0,0 +1,6 @@
+HTTP Server Handler
+===================
+
+Provides the `RequestHandlerInterface` of [PSR-15][psr-15].
+
+[psr-15]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-15-request-handlers.md
diff --git a/vendor/psr/http-server-handler/composer.json b/vendor/psr/http-server-handler/composer.json
new file mode 100644
index 00000000..9e8b51d1
--- /dev/null
+++ b/vendor/psr/http-server-handler/composer.json
@@ -0,0 +1,36 @@
+{
+    "name": "psr/http-server-handler",
+    "description": "Common interface for HTTP server-side request handler",
+    "keywords": [
+        "psr",
+        "psr-7",
+        "psr-15",
+        "http-interop",
+        "http",
+        "server",
+        "handler",
+        "request",
+        "response"
+    ],
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "PHP-FIG",
+            "homepage": "http://www.php-fig.org/"
+        }
+    ],
+    "require": {
+        "php": ">=7.0",
+        "psr/http-message": "^1.0"
+    },
+    "autoload": {
+        "psr-4": {
+            "Psr\\Http\\Server\\": "src/"
+        }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.0.x-dev"
+        }
+    }
+}
diff --git a/vendor/psr/http-server-handler/src/RequestHandlerInterface.php b/vendor/psr/http-server-handler/src/RequestHandlerInterface.php
new file mode 100644
index 00000000..83911e26
--- /dev/null
+++ b/vendor/psr/http-server-handler/src/RequestHandlerInterface.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Psr\Http\Server;
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+
+/**
+ * Handles a server request and produces a response.
+ *
+ * An HTTP request handler process an HTTP request in order to produce an
+ * HTTP response.
+ */
+interface RequestHandlerInterface
+{
+    /**
+     * Handles a request and produces a response.
+     *
+     * May call other collaborating code to generate the response.
+     */
+    public function handle(ServerRequestInterface $request): ResponseInterface;
+}
diff --git a/vendor/psr/http-server-middleware/LICENSE b/vendor/psr/http-server-middleware/LICENSE
new file mode 100644
index 00000000..b71ec5df
--- /dev/null
+++ b/vendor/psr/http-server-middleware/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 PHP Framework Interoperability Group
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/psr/http-server-middleware/README.md b/vendor/psr/http-server-middleware/README.md
new file mode 100644
index 00000000..8359bd05
--- /dev/null
+++ b/vendor/psr/http-server-middleware/README.md
@@ -0,0 +1,6 @@
+HTTP Server Middleware
+======================
+
+Provides the `MiddlewareInterface` of [PSR-15][psr-15].
+
+[psr-15]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-15-request-handlers.md
diff --git a/vendor/psr/http-server-middleware/composer.json b/vendor/psr/http-server-middleware/composer.json
new file mode 100644
index 00000000..1595513c
--- /dev/null
+++ b/vendor/psr/http-server-middleware/composer.json
@@ -0,0 +1,36 @@
+{
+    "name": "psr/http-server-middleware",
+    "description": "Common interface for HTTP server-side middleware",
+    "keywords": [
+        "psr",
+        "psr-7",
+        "psr-15",
+        "http-interop",
+        "http",
+        "middleware",
+        "request",
+        "response"
+    ],
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "PHP-FIG",
+            "homepage": "http://www.php-fig.org/"
+        }
+    ],
+    "require": {
+        "php": ">=7.0",
+        "psr/http-message": "^1.0",
+        "psr/http-server-handler": "^1.0"
+    },
+    "autoload": {
+        "psr-4": {
+            "Psr\\Http\\Server\\": "src/"
+        }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.0.x-dev"
+        }
+    }
+}
diff --git a/vendor/psr/http-server-middleware/src/MiddlewareInterface.php b/vendor/psr/http-server-middleware/src/MiddlewareInterface.php
new file mode 100644
index 00000000..a6c14f8c
--- /dev/null
+++ b/vendor/psr/http-server-middleware/src/MiddlewareInterface.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace Psr\Http\Server;
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+
+/**
+ * Participant in processing a server request and response.
+ *
+ * An HTTP middleware component participates in processing an HTTP message:
+ * by acting on the request, generating the response, or forwarding the
+ * request to a subsequent middleware and possibly acting on its response.
+ */
+interface MiddlewareInterface
+{
+    /**
+     * Process an incoming server request.
+     *
+     * Processes an incoming server request in order to produce a response.
+     * If unable to produce the response itself, it may delegate to the provided
+     * request handler to do so.
+     */
+    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface;
+}





More information about the tor-commits mailing list