@@ -141,29 +141,56 @@ export class HTTPClient {
141141 }
142142}
143143
144- export function matchContentType ( response : Response , pattern : string ) : boolean {
145- if ( pattern === "*" || pattern === "*/*" ) {
144+ // A semicolon surrounded by optional whitespace characters is used to separate
145+ // segments in a media type string.
146+ const mediaParamSeparator = / \s * ; \s * / g;
147+
148+ function matchContentType ( response : Response , pattern : string ) : boolean {
149+ // `*` is a special case which means anything is acceptable.
150+ if ( pattern === "*" ) {
146151 return true ;
147152 }
148153
149- const contentType =
150- response . headers . get ( "content-type" ) ?? "application/octet-stream" ;
154+ let contentType =
155+ response . headers . get ( "content-type" ) ?. trim ( ) || "application/octet-stream" ;
156+ contentType = contentType . toLowerCase ( ) ;
151157
152- const idx = contentType . split ( ";" ) . findIndex ( ( raw ) => {
153- const ctype = raw . trim ( ) ;
154- if ( ctype === pattern ) {
155- return true ;
156- }
158+ const wantParts = pattern . toLowerCase ( ) . trim ( ) . split ( mediaParamSeparator ) ;
159+ const [ wantType = "" , ...wantParams ] = wantParts ;
160+
161+ if ( wantType . split ( "/" ) . length !== 2 ) {
162+ return false ;
163+ }
164+
165+ const gotParts = contentType . split ( mediaParamSeparator ) ;
166+ const [ gotType = "" , ...gotParams ] = gotParts ;
167+
168+ const [ type = "" , subtype = "" ] = gotType . split ( "/" ) ;
169+ if ( ! type || ! subtype ) {
170+ return false ;
171+ }
157172
158- const parts = ctype . split ( "/" ) ;
159- if ( parts . length !== 2 ) {
173+ if (
174+ wantType !== "*/*" &&
175+ gotType !== wantType &&
176+ `${ type } /*` !== wantType &&
177+ `*/${ subtype } ` !== wantType
178+ ) {
179+ return false ;
180+ }
181+
182+ if ( gotParams . length < wantParams . length ) {
183+ return false ;
184+ }
185+
186+ const params = new Set ( gotParams ) ;
187+ for ( const wantParam of wantParams ) {
188+ if ( ! params . has ( wantParam ) ) {
160189 return false ;
161190 }
191+ }
162192
163- return `${ parts [ 0 ] } /*` === pattern || `*/${ parts [ 1 ] } ` === pattern ;
164- } ) ;
165-
166- return idx >= 0 ;
193+ return true ;
167194}
168195
169196const codeRangeRE = new RegExp ( "^[0-9]xx$" , "i" ) ;
0 commit comments