Redirect::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 3
crap 1
1
<?php
2
3
/*
4
 * This file is part of the Ivory Http Adapter package.
5
 *
6
 * (c) Eric GELOEN <[email protected]>
7
 *
8
 * For the full copyright and license information, please read the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Ivory\HttpAdapter\Event\Redirect;
13
14
use Ivory\HttpAdapter\HttpAdapterException;
15
use Ivory\HttpAdapter\HttpAdapterInterface;
16
use Ivory\HttpAdapter\Message\InternalRequestInterface;
17
use Ivory\HttpAdapter\Message\ResponseInterface;
18
19
/**
20
 * @author GeLo <[email protected]>
21
 */
22
class Redirect implements RedirectInterface
23
{
24
    /**
25
     * @var int
26
     */
27
    private $max;
28
29
    /**
30
     * @var bool
31
     */
32
    private $strict;
33
34
    /**
35
     * @var bool
36
     */
37
    private $throwException;
38
39
    /**
40
     * @param int  $max
41
     * @param bool $strict
42
     * @param bool $throwException
43
     */
44 270
    public function __construct($max = 5, $strict = false, $throwException = true)
45
    {
46 270
        $this->setMax($max);
47 270
        $this->setStrict($strict);
48 270
        $this->setThrowException($throwException);
49 270
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54 27
    public function getMax()
55
    {
56 27
        return $this->max;
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62 270
    public function setMax($max)
63
    {
64 270
        $this->max = $max;
65 270
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70 27
    public function isStrict()
71
    {
72 27
        return $this->strict;
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78 270
    public function setStrict($strict)
79
    {
80 270
        $this->strict = $strict;
81 270
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86 27
    public function getThrowException()
87
    {
88 27
        return $this->throwException;
89
    }
90
91
    /**
92
     * {@inheritdoc}
93
     */
94 270
    public function setThrowException($throwException)
95
    {
96 270
        $this->throwException = $throwException;
97 270
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102 207
    public function createRedirectRequest(
103
        ResponseInterface $response,
104
        InternalRequestInterface $internalRequest,
105
        HttpAdapterInterface $httpAdapter
106
    ) {
107 207
        if ($response->getStatusCode() < 300
108 203
            || $response->getStatusCode() >= 400
109 207
            || !$response->hasHeader('Location')) {
110 36
            return false;
111
        }
112
113 171
        if ($internalRequest->getParameter(self::REDIRECT_COUNT) >= $this->max) {
114 54
            if ($this->throwException) {
115 27
                $rootRequest = $this->getRootRequest($internalRequest);
116 27
                $exception = HttpAdapterException::maxRedirectsExceeded(
117 27
                    (string) $rootRequest->getUri(),
118 27
                    $this->max,
119 27
                    $httpAdapter->getName()
120 21
                );
121
122 27
                $exception->setRequest($rootRequest);
123
124 27
                throw $exception;
125
            }
126
127 27
            return false;
128
        }
129
130 117
        $strict = $response->getStatusCode() === 303 || (!$this->strict && $response->getStatusCode() <= 302);
131
132 117
        $headers = $internalRequest->getHeaders();
133
134 117
        foreach ($headers as $key => $value) {
135 117
            if (strtolower($key) === 'host') {
136 33
                unset($headers[$key]);
137 7
            }
138 91
        }
139
140 117
        $redirect = $httpAdapter->getConfiguration()->getMessageFactory()->createInternalRequest(
141 117
            $response->getHeaderLine('Location'),
142 117
            $strict ? InternalRequestInterface::METHOD_GET : $internalRequest->getMethod(),
143 117
            $internalRequest->getProtocolVersion(),
144 91
            $headers,
145 117
            $strict ? [] : $internalRequest->getDatas(),
146 117
            $strict ? [] : $internalRequest->getFiles(),
147 117
            $internalRequest->getParameters()
148 91
        );
149
150 117
        if ($strict) {
151 54
            $redirect = $redirect->withoutHeader('Content-Type')->withoutHeader('Content-Length');
152 42
        } else {
153 63
            $redirect = $redirect->withBody($internalRequest->getBody());
154
        }
155
156
        return $redirect
157 117
            ->withParameter(self::PARENT_REQUEST, $internalRequest)
158 117
            ->withParameter(self::REDIRECT_COUNT, $internalRequest->getParameter(self::REDIRECT_COUNT) + 1);
159
    }
160
161
    /**
162
     * {@inheritdoc}
163
     */
164 9
    public function prepareResponse(ResponseInterface $response, InternalRequestInterface $internalRequest)
165
    {
166
        return $response
167 9
            ->withParameter(self::REDIRECT_COUNT, (int) $internalRequest->getParameter(self::REDIRECT_COUNT))
168 9
            ->withParameter(self::EFFECTIVE_URI, (string) $internalRequest->getUri());
169
    }
170
171
    /**
172
     * {@inheritdoc}
173
     */
174 27
    private function getRootRequest(InternalRequestInterface $internalRequest)
175
    {
176 27
        if ($internalRequest->hasParameter(self::PARENT_REQUEST)) {
177 27
            return $this->getRootRequest($internalRequest->getParameter(self::PARENT_REQUEST));
178
        }
179
180 27
        return $internalRequest;
181
    }
182
}
183