@@ -67,34 +67,10 @@ extension Converter {
67
67
guard let parsedAcceptValue = OpenAPIMIMEType ( acceptValue) else {
68
68
throw RuntimeError . invalidExpectedContentType ( acceptValue)
69
69
}
70
- switch ( parsedAcceptValue. kind, parsedSubstring. kind) {
71
- case ( . any, _) :
72
- // Accept: */* always matches
73
- return
74
- case ( . anySubtype( type: let acceptType) , let substring) :
75
- switch substring {
76
- case . any:
77
- // */* as a concrete content type is NOT a match for an Accept header of foo/*
78
- break
79
- case . anySubtype( type: let substringType) :
80
- // Only match if the types match.
81
- if substringType. lowercased ( ) == acceptType. lowercased ( ) { return }
82
- case . concrete( type: let substringType, _) :
83
- if substringType. lowercased ( ) == acceptType. lowercased ( ) { return }
84
- }
85
- case ( . concrete( type: let acceptType, subtype: let acceptSubtype) , let substring) :
86
- if case let . concrete( substringType, substringSubtype) = substring {
87
- if acceptType. lowercased ( ) == substringType. lowercased ( )
88
- && acceptSubtype. lowercased ( ) == substringSubtype. lowercased ( )
89
- {
90
- return
91
- }
92
- }
93
- }
70
+ if parsedSubstring. satisfies ( acceptValue: parsedAcceptValue) { return }
94
71
}
95
72
throw RuntimeError . unexpectedAcceptHeader ( acceptHeader)
96
73
}
97
-
98
74
/// Retrieves and decodes a path parameter as a URI-encoded value of the specified type.
99
75
///
100
76
/// - Parameters:
@@ -500,3 +476,27 @@ extension Converter {
500
476
)
501
477
}
502
478
}
479
+
480
+ fileprivate extension OpenAPIMIMEType {
481
+ /// Checks if the type satisfies the provided Accept header value.
482
+ /// - Parameter acceptValue: A parsed Accept header MIME type.
483
+ /// - Returns: `true` if it satisfies the Accept header, `false` otherwise.
484
+ func satisfies( acceptValue: OpenAPIMIMEType ) -> Bool {
485
+ switch ( acceptValue. kind, self . kind) {
486
+ case ( . concrete, . any) , ( . concrete, . anySubtype) , ( . anySubtype, . any) :
487
+ // The response content-type must be at least as specific as the accept header.
488
+ return false
489
+ case ( . any, _) :
490
+ // Accept: */* -- Any content-type satisfies the accept header.
491
+ return true
492
+ case ( . anySubtype( let acceptType) , . anySubtype( let substringType) ) ,
493
+ ( . anySubtype( let acceptType) , . concrete( let substringType, _) ) :
494
+ // Accept: type/* -- The content-type should match the partially-specified accept header.
495
+ return acceptType. lowercased ( ) == substringType. lowercased ( )
496
+ case ( . concrete( let acceptType, let acceptSubtype) , . concrete( let substringType, let substringSubtype) ) :
497
+ // Accept: type/subtype -- The content-type should match the concrete type.
498
+ return acceptType. lowercased ( ) == substringType. lowercased ( )
499
+ && acceptSubtype. lowercased ( ) == substringSubtype. lowercased ( )
500
+ }
501
+ }
502
+ }
0 commit comments