11
11
12
12
namespace Asm89 \Stack ;
13
13
14
- use Symfony \Component \HttpKernel \HttpKernelInterface ;
15
14
use Symfony \Component \HttpFoundation \Request ;
16
15
use Symfony \Component \HttpFoundation \Response ;
17
16
@@ -55,9 +54,12 @@ private function normalizeOptions(array $options = array())
55
54
return $ options ;
56
55
}
57
56
57
+ /**
58
+ * @deprecated use isOriginAllowed
59
+ */
58
60
public function isActualRequestAllowed (Request $ request )
59
61
{
60
- return $ this ->checkOrigin ($ request );
62
+ return $ this ->isOriginAllowed ($ request );
61
63
}
62
64
63
65
public function isCorsRequest (Request $ request )
@@ -72,134 +74,156 @@ public function isPreflightRequest(Request $request)
72
74
&& $ request ->headers ->has ('Access-Control-Request-Method ' );
73
75
}
74
76
75
- public function addActualRequestHeaders ( Response $ response , Request $ request )
77
+ public function handlePreflightRequest ( Request $ request )
76
78
{
77
- if (!$ this ->checkOrigin ($ request )) {
78
- return $ response ;
79
- }
79
+ $ response = new Response ();
80
80
81
- $ response ->headers -> set ( ' Access-Control-Allow-Origin ' , $ request -> headers -> get ( ' Origin ' ) );
81
+ $ response ->setStatusCode ( 204 );
82
82
83
- if (!$ response ->headers ->has ('Vary ' )) {
84
- $ response ->headers ->set ('Vary ' , 'Origin ' );
85
- } else {
86
- $ response ->headers ->set ('Vary ' , $ response ->headers ->get ('Vary ' ) . ', Origin ' );
87
- }
83
+ return $ this ->addPreflightRequestHeaders ($ response , $ request );
84
+ }
88
85
89
- if ( $ this -> options [ ' supportsCredentials ' ]) {
90
- $ response -> headers -> set ( ' Access-Control-Allow-Credentials ' , ' true ' );
91
- }
86
+ public function addPreflightRequestHeaders ( Response $ response , Request $ request )
87
+ {
88
+ $ this -> configureAllowedOrigin ( $ response , $ request );
92
89
93
- if ($ this ->options ['exposedHeaders ' ]) {
94
- $ response ->headers ->set ('Access-Control-Expose-Headers ' , implode (', ' , $ this ->options ['exposedHeaders ' ]));
95
- }
90
+ $ this ->configureAllowCredentials ($ response , $ request );
91
+
92
+ $ this ->configureAllowedMethods ($ response , $ request );
93
+
94
+ $ this ->configureAllowedHeaders ($ response , $ request );
95
+
96
+ $ this ->configureMaxAge ($ response , $ request );
96
97
97
98
return $ response ;
98
99
}
99
100
100
- public function handlePreflightRequest (Request $ request )
101
+ public function isOriginAllowed (Request $ request )
101
102
{
102
- if (true !== $ check = $ this -> checkPreflightRequestConditions ( $ request ) ) {
103
- return $ check ;
103
+ if ($ this -> options [ ' allowedOrigins ' ] === true ) {
104
+ return true ;
104
105
}
105
106
106
- return $ this ->buildPreflightCheckResponse ($ request );
107
- }
107
+ if (!$ request ->headers ->has ('Origin ' )) {
108
+ return false ;
109
+ }
108
110
109
- private function buildPreflightCheckResponse (Request $ request )
110
- {
111
- $ response = new Response ();
111
+ $ origin = $ request ->headers ->get ('Origin ' );
112
112
113
- if ($ this ->options ['supportsCredentials ' ] ) {
114
- $ response -> headers -> set ( ' Access-Control-Allow-Credentials ' , ' true ' ) ;
113
+ if (in_array ( $ origin , $ this ->options ['allowedOrigins ' ]) ) {
114
+ return true ;
115
115
}
116
116
117
- $ response -> headers -> set ( ' Access-Control-Allow-Origin ' , $ request -> headers -> get ( ' Origin ' ));
118
-
119
- if ( $ this -> options [ ' maxAge ' ] !== null ) {
120
- $ response -> headers -> set ( ' Access-Control-Max-Age ' , $ this -> options [ ' maxAge ' ]);
117
+ foreach ( $ this -> options [ ' allowedOriginsPatterns ' ] as $ pattern ) {
118
+ if ( preg_match ( $ pattern , $ origin )) {
119
+ return true ;
120
+ }
121
121
}
122
122
123
- $ allowMethods = $ this ->options ['allowedMethods ' ] === true
124
- ? strtoupper ($ request ->headers ->get ('Access-Control-Request-Method ' ))
125
- : implode (', ' , $ this ->options ['allowedMethods ' ]);
126
- $ response ->headers ->set ('Access-Control-Allow-Methods ' , $ allowMethods );
123
+ return false ;
124
+ }
127
125
128
- $ allowHeaders = $ this ->options ['allowedHeaders ' ] === true
129
- ? strtoupper ($ request ->headers ->get ('Access-Control-Request-Headers ' ))
130
- : implode (', ' , $ this ->options ['allowedHeaders ' ]);
131
- $ response ->headers ->set ('Access-Control-Allow-Headers ' , $ allowHeaders );
126
+ public function addActualRequestHeaders (Response $ response , Request $ request )
127
+ {
128
+ $ this ->configureAllowedOrigin ($ response , $ request );
132
129
133
- $ response ->setStatusCode (204 );
130
+ $ this ->configureAllowCredentials ($ response , $ request );
131
+
132
+ $ this ->configureExposedHeaders ($ response , $ request );
134
133
135
134
return $ response ;
136
135
}
137
136
138
- private function checkPreflightRequestConditions ( Request $ request )
137
+ private function configureAllowedOrigin ( Response $ response , Request $ request )
139
138
{
140
- if (!$ this ->checkOrigin ($ request )) {
141
- return $ this ->createBadRequestResponse (403 , 'Origin not allowed ' );
139
+ if ($ this ->options ['allowedOrigins ' ] === true && !$ this ->options ['supportsCredentials ' ]) {
140
+ // Safe+cacheable, allow everything
141
+ $ response ->headers ->set ('Access-Control-Allow-Origin ' , '* ' );
142
+ } elseif ($ this ->isSingleOriginAllowed ()) {
143
+ // Single origins can be safely set
144
+ $ response ->headers ->set ('Access-Control-Allow-Origin ' , array_values ($ this ->options ['allowedOrigins ' ])[0 ]);
145
+ } else {
146
+ // For dynamic headers, check the origin first
147
+ if ($ this ->isOriginAllowed ($ request )) {
148
+ $ response ->headers ->set ('Access-Control-Allow-Origin ' , $ request ->headers ->get ('Origin ' ));
149
+ }
150
+
151
+ $ this ->varyHeader ($ response , 'Origin ' );
142
152
}
153
+ }
143
154
144
- if (!$ this ->checkMethod ($ request )) {
145
- return $ this ->createBadRequestResponse (405 , 'Method not allowed ' );
155
+ private function isSingleOriginAllowed ()
156
+ {
157
+ if ($ this ->options ['allowedOrigins ' ] === true || !empty ($ this ->options ['allowedOriginsPatterns ' ])) {
158
+ return false ;
146
159
}
147
160
148
- $ requestHeaders = array ();
149
- // if allowedHeaders has been set to true ('*' allow all flag) just skip this check
150
- if ($ this ->options ['allowedHeaders ' ] !== true && $ request ->headers ->has ('Access-Control-Request-Headers ' )) {
151
- $ headers = strtolower ($ request ->headers ->get ('Access-Control-Request-Headers ' ));
152
- $ requestHeaders = array_filter (explode (', ' , $ headers ));
161
+ return count ($ this ->options ['allowedOrigins ' ]) === 1 ;
162
+ }
153
163
154
- foreach ($ requestHeaders as $ header ) {
155
- if (!in_array (trim ($ header ), $ this ->options ['allowedHeaders ' ])) {
156
- return $ this ->createBadRequestResponse (403 , 'Header not allowed ' );
157
- }
164
+ private function configureAllowedMethods (Response $ response , Request $ request )
165
+ {
166
+ if ($ this ->options ['allowedMethods ' ] === true ) {
167
+ if ($ this ->options ['supportsCredentials ' ]) {
168
+ $ allowMethods = strtoupper ($ request ->headers ->get ('Access-Control-Request-Method ' ));
169
+ $ this ->varyHeader ($ response , 'Access-Control-Request-Method ' );
170
+ } else {
171
+ $ allowMethods = '* ' ;
158
172
}
173
+ } else {
174
+ $ allowMethods = implode (', ' , $ this ->options ['allowedMethods ' ]);
159
175
}
160
176
161
- return true ;
177
+ $ response -> headers -> set ( ' Access-Control-Allow-Methods ' , $ allowMethods ) ;
162
178
}
163
179
164
- private function createBadRequestResponse ( $ code , $ reason = '' )
180
+ private function configureAllowedHeaders ( Response $ response , Request $ request )
165
181
{
166
- return new Response ($ reason , $ code );
182
+ if ($ this ->options ['allowedHeaders ' ] === true ) {
183
+ if ($ this ->options ['supportsCredentials ' ]) {
184
+ $ allowHeaders = strtoupper ($ request ->headers ->get ('Access-Control-Request-Headers ' ));
185
+ $ this ->varyHeader ($ response , 'Access-Control-Request-Headers ' );
186
+ } else {
187
+ $ allowHeaders = '* ' ;
188
+ }
189
+ } else {
190
+ $ allowHeaders = implode (', ' , $ this ->options ['allowedHeaders ' ]);
191
+ }
192
+ $ response ->headers ->set ('Access-Control-Allow-Headers ' , $ allowHeaders );
167
193
}
168
194
169
- private function isSameHost ( Request $ request )
195
+ private function configureAllowCredentials ( Response $ response , Request $ request )
170
196
{
171
- return $ request ->headers ->get ('Origin ' ) === $ request ->getSchemeAndHttpHost ();
197
+ if ($ this ->options ['supportsCredentials ' ]) {
198
+ $ response ->headers ->set ('Access-Control-Allow-Credentials ' , 'true ' );
199
+ }
172
200
}
173
201
174
- private function checkOrigin ( Request $ request )
202
+ private function configureExposedHeaders ( Response $ response , Request $ request )
175
203
{
176
- if ($ this ->options ['allowedOrigins ' ] === true ) {
177
- // allow all '*' flag
178
- return true ;
179
- }
180
- $ origin = $ request ->headers ->get ('Origin ' );
181
-
182
- if (in_array ($ origin , $ this ->options ['allowedOrigins ' ])) {
183
- return true ;
204
+ if ($ this ->options ['exposedHeaders ' ]) {
205
+ $ response ->headers ->set ('Access-Control-Expose-Headers ' , implode (', ' , $ this ->options ['exposedHeaders ' ]));
184
206
}
207
+ }
185
208
186
- foreach ( $ this -> options [ ' allowedOriginsPatterns ' ] as $ pattern ) {
187
- if ( preg_match ( $ pattern , $ origin )) {
188
- return true ;
189
- }
209
+ private function configureMaxAge ( Response $ response , Request $ request )
210
+ {
211
+ if ( $ this -> options [ ' maxAge ' ] !== null ) {
212
+ $ response -> headers -> set ( ' Access-Control-Max-Age ' , ( int ) $ this -> options [ ' maxAge ' ]);
190
213
}
191
-
192
- return false ;
193
214
}
194
215
195
- private function checkMethod ( Request $ request )
216
+ private function varyHeader ( Response $ response , $ header )
196
217
{
197
- if ($ this ->options ['allowedMethods ' ] === true ) {
198
- // allow all '*' flag
199
- return true ;
218
+ if (!$ response ->headers ->has ('Vary ' )) {
219
+ $ response ->headers ->set ('Vary ' , $ header );
220
+ } else {
221
+ $ response ->headers ->set ('Vary ' , $ response ->headers ->get ('Vary ' ) . ', ' . $ header );
200
222
}
223
+ }
201
224
202
- $ requestMethod = strtoupper ($ request ->headers ->get ('Access-Control-Request-Method ' ));
203
- return in_array ($ requestMethod , $ this ->options ['allowedMethods ' ]);
225
+ private function isSameHost (Request $ request )
226
+ {
227
+ return $ request ->headers ->get ('Origin ' ) === $ request ->getSchemeAndHttpHost ();
204
228
}
205
229
}
0 commit comments