Completed
Push — master ( 00ed35...63fbb3 )
by Oscar
10:20
created

Cors::settings()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 6
rs 9.4286
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace Psr7Middlewares\Middleware;
4
5
use Psr\Http\Message\ServerRequestInterface;
6
use Psr\Http\Message\ResponseInterface;
7
use Neomerx\Cors\Analyzer;
8
use Neomerx\Cors\Contracts\AnalysisResultInterface;
9
use Neomerx\Cors\Contracts\Strategies\SettingsStrategyInterface;
10
use Neomerx\Cors\Strategies\Settings;
11
12
/**
13
 * Middleware to implement Cors.
14
 */
15
class Cors
16
{
17
    /**
18
     * @var SettingsStrategyInterface The settings used by the Analyzer
19
     */
20
    private $settings;
21
22
    /**
23
     * Defines the settings used.
24
     *
25
     * @param SettingsStrategyInterface|null $settings
26
     */
27
    public function __construct(SettingsStrategyInterface $settings = null)
28
    {
29
        $this->settings = $settings ?: new Settings();
30
    }
31
32
    /**
33
     * Set the server origin.
34
     * 
35
     * @see Neomerx\Cors\Contracts\Strategies::setServerOrigin
36
     * 
37
     * @param string|array $origin
38
     * 
39
     * @return self
40
     */
41
    public function origin($origin)
42
    {
43
        $this->settings->setServerOrigin($origin);
44
45
        return $this;
46
    }
47
48
    /**
49
     * Set allowed origins.
50
     * 
51
     * @see Neomerx\Cors\Contracts\Strategies::setRequestAllowedOrigins
52
     * 
53
     * @param array $origins
54
     * 
55
     * @return self
56
     */
57
    public function allowedOrigins(array $origins)
58
    {
59
        $this->settings->setRequestAllowedOrigins($origins);
60
61
        return $this;
62
    }
63
64
    /**
65
     * Set allowed methods.
66
     * 
67
     * @see Neomerx\Cors\Contracts\Strategies::setRequestAllowedMethods
68
     * @see Neomerx\Cors\Contracts\Strategies::setForceAddAllowedMethodsToPreFlightResponse
69
     * 
70
     * @param array $methods
71
     * @param bool  $force   If allowed methods should be added to pre-flight response
72
     * 
73
     * @return self
74
     */
75
    public function allowedMethods(array $methods, $force = false)
76
    {
77
        $this->settings->setRequestAllowedMethods($methods);
78
        $this->settings->setForceAddAllowedMethodsToPreFlightResponse($force);
79
80
        return $this;
81
    }
82
83
    /**
84
     * Set allowed headers.
85
     * 
86
     * @see Neomerx\Cors\Contracts\Strategies::setRequestAllowedHeaders
87
     * @see Neomerx\Cors\Contracts\Strategies::setForceAddAllowedHeadersToPreFlightResponse
88
     * 
89
     * @param array $headers
90
     * @param bool  $force   If allowed headers should be added to pre-flight response
91
     * 
92
     * @return self
93
     */
94
    public function allowedHeaders(array $headers, $force = false)
95
    {
96
        $this->settings->setRequestAllowedHeaders($headers);
97
        $this->settings->setForceAddAllowedHeadersToPreFlightResponse($force);
98
99
        return $this;
100
    }
101
102
    /**
103
     * Set headers other than the simple ones that might be exposed to user agent.
104
     * 
105
     * @see Neomerx\Cors\Contracts\Strategies::setResponseExposedHeaders
106
     * 
107
     * @param array $headers
108
     * 
109
     * @return self
110
     */
111
    public function exposedHeaders(array $headers)
112
    {
113
        $this->settings->setResponseExposedHeaders($headers);
114
115
        return $this;
116
    }
117
118
    /**
119
     * If access with credentials is supported by the resource.
120
     * 
121
     * @see Neomerx\Cors\Contracts\Strategies::setRequestCredentialsSupported
122
     * 
123
     * @param bool $allow
124
     * 
125
     * @return self
126
     */
127
    public function allowCredentials($allow = true)
128
    {
129
        $this->settings->setRequestCredentialsSupported($allow);
130
131
        return $this;
132
    }
133
134
    /**
135
     * Set pre-flight cache max period in seconds.
136
     * 
137
     * @see Neomerx\Cors\Contracts\Strategies::setPreFlightCacheMaxAge
138
     * 
139
     * @param int $maxAge
140
     * 
141
     * @return self
142
     */
143
    public function maxAge($maxAge)
144
    {
145
        $this->settings->setPreFlightCacheMaxAge($maxAge);
146
147
        return $this;
148
    }
149
150
    /**
151
     * If request 'Host' header should be checked against server's origin.
152
     * 
153
     * @see Neomerx\Cors\Contracts\Strategies::setCheckHost
154
     * 
155
     * @param bool $checkHost
156
     * 
157
     * @return self
158
     */
159
    public function checkHost($checkHost = true)
160
    {
161
        $this->settings->setCheckHost($checkHost);
162
163
        return $this;
164
    }
165
166
    /**
167
     * Execute the middleware.
168
     *
169
     * @param ServerRequestInterface $request
170
     * @param ResponseInterface      $response
171
     * @param callable               $next
172
     *
173
     * @return ResponseInterface
174
     */
175
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next)
176
    {
177
        $cors = Analyzer::instance($this->settings)->analyze($request);
178
179
        switch ($cors->getRequestType()) {
180
            case AnalysisResultInterface::ERR_NO_HOST_HEADER:
181
            case AnalysisResultInterface::ERR_ORIGIN_NOT_ALLOWED:
182
            case AnalysisResultInterface::ERR_METHOD_NOT_SUPPORTED:
183
            case AnalysisResultInterface::ERR_HEADERS_NOT_SUPPORTED:
184
                return $response->withStatus(403);
185
186
            case AnalysisResultInterface::TYPE_REQUEST_OUT_OF_CORS_SCOPE:
187
                return $next($request, $response);
188
189
            case AnalysisResultInterface::TYPE_PRE_FLIGHT_REQUEST:
190
                foreach ($cors->getResponseHeaders() as $name => $value) {
191
                    $response = $response->withHeader($name, $value);
192
                }
193
194
                return $response->withStatus(200);
195
196
            default:
197
                $response = $next($request, $response);
198
199
                foreach ($cors->getResponseHeaders() as $name => $value) {
200
                    $response = $response->withHeader($name, $value);
201
                }
202
203
                return $response;
204
        }
205
    }
206
}
207