Completed
Push — master ( c6fce1...3b2b6f )
by Steven
02:14
created

ProviderRedirectTrait::followRequestRedirects()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 21
ccs 14
cts 14
cp 1
rs 9.3142
cc 3
eloc 13
nc 3
nop 1
crap 3
1
<?php
2
3
namespace Stevenmaguire\OAuth2\Client\Tool;
4
5
use GuzzleHttp\Exception\BadResponseException;
6
use GuzzleHttp\Psr7\Uri;
7
use InvalidArgumentException;
8
use Psr\Http\Message\RequestInterface;
9
use Psr\Http\Message\ResponseInterface;
10
11
trait ProviderRedirectTrait
12
{
13
    /**
14
     * Maximum number of times to follow provider initiated redirects
15
     *
16
     * @var integer
17
     */
18
    protected $redirectLimit = 2;
19
20
    /**
21
     * Retrieves a response for a given request and retrieves subsequent
22
     * responses, with authorization headers, if a redirect is detected.
23
     *
24
     * @param  RequestInterface $request
25
     * @return ResponseInterface
26
     * @throws BadResponseException
27
     */
28 8
    protected function followRequestRedirects(RequestInterface $request)
29
    {
30 8
        $response = null;
31 8
        $attempts = 0;
32
33 8
        while ($attempts < $this->redirectLimit) {
34 8
            $attempts++;
35 8
            $response = $this->getHttpClient()->send($request, [
36
                'allow_redirects' => false
37 8
            ]);
38
39 6
            if ($this->isRedirect($response)) {
40 2
                $redirectUrl = new Uri($response->getHeader('Location')[0]);
41 2
                $request = $request->withUri($redirectUrl);
42 2
            } else {
43 4
                break;
44
            }
45 2
        }
46
47 6
        return $response;
48
    }
49
50
    /**
51
     * Returns the HTTP client instance.
52
     *
53
     * @return GuzzleHttp\ClientInterface
54
     */
55
    abstract public function getHttpClient();
56
57
    /**
58
     * Retrieves current redirect limit.
59
     *
60
     * @return integer
61
     */
62 4
    public function getRedirectLimit()
63
    {
64 4
        return $this->redirectLimit;
65
    }
66
67
    /**
68
     * Determines if a given response is a redirect.
69
     *
70
     * @param  ResponseInterface  $response
71
     *
72
     * @return boolean
73
     */
74 6
    protected function isRedirect(ResponseInterface $response)
75
    {
76 6
        $statusCode = $response->getStatusCode();
77
78 6
        return $statusCode > 300 && $statusCode < 400 && $response->hasHeader('Location');
79
    }
80
81
    /**
82
     * Sends a request instance and returns a response instance.
83
     *
84
     * @param  RequestInterface $request
85
     * @return ResponseInterface
86
     */
87 8
    protected function sendRequest(RequestInterface $request)
88
    {
89
        try {
90 8
            $response = $this->followRequestRedirects($request);
91 8
        } catch (BadResponseException $e) {
92 2
            $response = $e->getResponse();
93
        }
94
95 8
        return $response;
96
    }
97
98
    /**
99
     * Updates the redirect limit.
100
     *
101
     * @param integer $limit
102
     * @return League\OAuth2\Client\Provider\AbstractProvider
103
     * @throws InvalidArgumentException
104
     */
105 14
    public function setRedirectLimit($limit)
106
    {
107 14
        if (!is_int($limit)) {
108 4
            throw new InvalidArgumentException('redirectLimit must be an integer.');
109
        }
110
111 10
        if ($limit < 1) {
112 4
            throw new InvalidArgumentException('redirectLimit must be greater than or equal to one.');
113
        }
114
115 6
        $this->redirectLimit = $limit;
116
117 6
        return $this;
118
    }
119
}
120