@@ -79,6 +79,18 @@ pub struct Cors {
79
79
/// preflight request is always an OPTIONS and doesn't use the same method as
80
80
/// the actual request.
81
81
pub ( crate ) request_method : Option < String > ,
82
+ /// The HTTP Cross-Origin-Embedder-Policy (COEP) response header prevents a
83
+ /// document from loading any cross-origin resources that don't explicitly
84
+ /// grant the document permission (using CORP or CORS).
85
+ ///
86
+ /// Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy
87
+ pub ( crate ) embedder_policy : Option < String > ,
88
+ /// The HTTP Cross-Origin-Opener-Policy (COOP) response header allows you to
89
+ /// ensure a top-level document does not share a browsing context group with
90
+ /// cross-origin documents.
91
+ ///
92
+ /// Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy
93
+ pub ( crate ) opener_policy : Option < String > ,
82
94
}
83
95
84
96
impl Cors {
@@ -156,6 +168,32 @@ impl Cors {
156
168
) ) ;
157
169
}
158
170
171
+ if let Some ( embedder_policy) = cors. embedder_policy {
172
+ // TODO: Validate possible directives
173
+ //
174
+ // Cross-Origin-Embedder-Policy: unsafe-none | require-corp
175
+ //
176
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy#directives
177
+ cors_headers. push ( (
178
+ HeaderName :: from_static ( "Cross-Origin-Embedder-Policy" ) ,
179
+ HeaderValue :: from_str ( & embedder_policy. as_str ( ) ) . unwrap ( ) ,
180
+ ) ) ;
181
+ }
182
+
183
+ if let Some ( opener_policy) = cors. opener_policy {
184
+ // TODO: Validate possible directives
185
+ //
186
+ // Cross-Origin-Opener-Policy: unsafe-none
187
+ // Cross-Origin-Opener-Policy: same-origin-allow-popups
188
+ // Cross-Origin-Opener-Policy: same-origin
189
+ //
190
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy#directives
191
+ cors_headers. push ( (
192
+ HeaderName :: from_static ( "Cross-Origin-Opener-Policy" ) ,
193
+ HeaderValue :: from_str ( & opener_policy. as_str ( ) ) . unwrap ( ) ,
194
+ ) ) ;
195
+ }
196
+
159
197
cors_headers
160
198
}
161
199
}
@@ -206,6 +244,16 @@ impl CorsBuilder {
206
244
self
207
245
}
208
246
247
+ pub fn embedder_policy ( mut self , embedder_policy : String ) -> Self {
248
+ self . config . embedder_policy = Some ( embedder_policy) ;
249
+ self
250
+ }
251
+
252
+ pub fn opener_policy ( mut self , opener_policy : String ) -> Self {
253
+ self . config . opener_policy = Some ( opener_policy) ;
254
+ self
255
+ }
256
+
209
257
pub fn build ( self ) -> Cors {
210
258
self . config
211
259
}
@@ -249,6 +297,14 @@ impl TryFrom<CorsConfig> for Cors {
249
297
builder = builder. request_method ( request_method) ;
250
298
}
251
299
300
+ if let Some ( embedder_policy) = value. embedder_policy {
301
+ builder = builder. embedder_policy ( embedder_policy) ;
302
+ }
303
+
304
+ if let Some ( opener_policy) = value. opener_policy {
305
+ builder = builder. opener_policy ( opener_policy) ;
306
+ }
307
+
252
308
Ok ( builder. build ( ) )
253
309
}
254
310
}
@@ -360,6 +416,7 @@ mod tests {
360
416
max_age : Some ( max_age) ,
361
417
request_headers : Some ( request_headers. clone ( ) ) ,
362
418
request_method : Some ( request_method. clone ( ) ) ,
419
+ ..Default :: default ( )
363
420
} ;
364
421
let cors = Cors {
365
422
allow_credentials : true ,
@@ -370,6 +427,7 @@ mod tests {
370
427
max_age : Some ( max_age) ,
371
428
request_headers : Some ( request_headers) ,
372
429
request_method : Some ( request_method) ,
430
+ ..Default :: default ( )
373
431
} ;
374
432
375
433
assert_eq ! ( cors, Cors :: try_from( config) . unwrap( ) ) ;
0 commit comments