Issues (6)

src/ClientMiddleware.php (1 issue)

1
<?php declare(strict_types=1);
2
3
namespace Jasny\HttpDigest;
4
5
use Http\Client\Common\Plugin as HttpPlugin;
6
use Http\Promise\Promise as HttpPromise;
7
use Psr\Http\Message\RequestInterface;
8
use Psr\Http\Message\ResponseInterface;
9
10
/**
11
 * Middleware to sign PSR-7 HTTP requests.
12
 */
13
class ClientMiddleware
14
{
15
    /**
16
     * @var HttpDigest
17
     */
18
    protected $service;
19
20
    /**
21
     * Class constructor.
22
     *
23
     * @param HttpDigest $service
24
     */
25 32
    public function __construct(HttpDigest $service)
26
    {
27 32
        $this->service = $service;
28 32
    }
29
30
31
    /**
32
     * Return a callback that can be used as double pass middleware.
33
     *
34
     * @return callable
35
     */
36 9
    public function asDoublePass(): callable
37
    {
38
        return function (RequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface {
39 9
            $nextRequest = $this->shouldHaveDigest($request) ? $this->addDigest($request) : $request;
40 9
            return $next($nextRequest, $response);
41 9
        };
42
    }
43
44
    /**
45
     * Return a callback that can be used as Guzzle middleware.
46
     * @see http://docs.guzzlephp.org/en/stable/handlers-and-middleware.html
47
     *
48
     * @return callable
49
     */
50 14
    public function forGuzzle(): callable
51
    {
52
        return function (callable $handler) {
53
            return function (RequestInterface $request, array $options) use ($handler) {
54 14
                $nextRequest = $this->shouldHaveDigest($request) ? $this->addDigest($request) : $request;
55 14
                return $handler($nextRequest, $options);
56 14
            };
57 14
        };
58
    }
59
60
    /**
61
     * Create a version of this middleware that can be used in HTTPlug.
62
     * @see http://docs.php-http.org/en/latest/plugins/introduction.html
63
     *
64
     * @return self&HttpPlugin
0 ignored issues
show
Documentation Bug introduced by
The doc comment self&HttpPlugin at position 0 could not be parsed: 'self' is only available from within classes.
Loading history...
65
     */
66
    public function forHttplug(): HttpPlugin
67
    {
68
        return new class ($this->service) extends ClientMiddleware implements HttpPlugin {
69 9
            public function handleRequest(RequestInterface $request, callable $next, callable $first): HttpPromise
70
            {
71 9
                $nextRequest = $this->shouldHaveDigest($request) ? $this->addDigest($request) : $request;
72 9
                return $next($nextRequest);
73
            }
74
        };
75
    }
76
77
78
    /**
79
     * Check if a digest header should be added to the request.
80
     *
81
     * @param RequestInterface $request
82
     * @return bool
83
     */
84 32
    protected function shouldHaveDigest(RequestInterface $request)
85
    {
86 32
        switch (strtoupper($request->getMethod())) {
87 32
            case 'GET':
88 29
            case 'HEAD':
89 26
            case 'OPTIONS':
90 6
                return false;
91
92 26
            case 'PATCH':
93 22
            case 'POST':
94 18
            case 'PUT':
95 12
                return true;
96
97
            default:
98 14
                return $request->getBody()->getSize() > 0;
99
        }
100
    }
101
102
    /**
103
     * Add a digest header to the request.
104
     *
105
     * @param RequestInterface $request
106
     * @return RequestInterface
107
     * @throws \RuntimeException if unable to read or an error occurs while reading
108
     */
109 20
    protected function addDigest(RequestInterface $request): RequestInterface
110
    {
111 20
        $digest = $this->service->create($request->getBody()->getContents());
112
113 20
        return $request->withHeader('Digest', $digest);
114
    }
115
}
116