@@ -34,7 +34,7 @@ class ResourceMapper {
3434 this . _defaultContentType = defaultContentType
3535 this . _types = { ...types , ...overrideTypes }
3636 this . _indexFilename = indexFilename
37- this . _indexContentType = this . _getContentTypeByExtension ( indexFilename )
37+ this . _indexContentType = this . _getContentTypeFromExtension ( indexFilename )
3838
3939 // If the host needs to be replaced on every call, pre-split the root URL
4040 if ( includeHost ) {
@@ -82,7 +82,7 @@ class ResourceMapper {
8282 const url = `${ this . resolveUrl ( hostname ) } ${
8383 pathname . split ( pathUtil . sep ) . map ( ( component ) => encodeURIComponent ( component ) ) . join ( '/' )
8484 } `
85- return { url, contentType : this . _getContentTypeByExtension ( path ) }
85+ return { url, contentType : this . _getContentTypeFromExtension ( path ) }
8686 }
8787
8888 // Maps the request for a given resource and representation format to a server file
@@ -97,7 +97,7 @@ class ResourceMapper {
9797 let isFolder = filePath . endsWith ( '/' )
9898 let isIndex = searchIndex && filePath . endsWith ( '/' )
9999
100- // Create the path for a new ressource
100+ // Create the path for a new resource
101101 let path
102102 if ( createIfNotExists ) {
103103 path = filePath
@@ -109,8 +109,8 @@ class ResourceMapper {
109109 path += this . _indexFilename
110110 }
111111 // If the extension is not correct for the content type, append the correct extension
112- if ( ! isFolder && this . _getContentTypeByExtension ( path ) !== contentType ) {
113- path += `$ ${ contentType in extensions ? `. ${ extensions [ contentType ] [ 0 ] } ` : '.unknown' } `
112+ if ( ! isFolder ) {
113+ path = this . _addContentTypeExtension ( path , contentType )
114114 }
115115 // Determine the path of an existing file
116116 } else {
@@ -139,7 +139,7 @@ class ResourceMapper {
139139 }
140140 }
141141 path = `${ folder } ${ match } `
142- contentType = this . _getContentTypeByExtension ( match )
142+ contentType = this . _getContentTypeFromExtension ( match )
143143 }
144144 return { path, contentType : contentType || this . _defaultContentType }
145145 }
@@ -160,11 +160,25 @@ class ResourceMapper {
160160 }
161161
162162 // Gets the expected content type based on the extension of the path
163- _getContentTypeByExtension ( path ) {
163+ _getContentTypeFromExtension ( path ) {
164164 const extension = / \. ( [ ^ / . ] + ) $ / . exec ( path )
165165 return extension && this . _types [ extension [ 1 ] . toLowerCase ( ) ] || this . _defaultContentType
166166 }
167167
168+ // Appends an extension for the specific content type, if needed
169+ _addContentTypeExtension ( path , contentType ) {
170+ // If we would guess the wrong content type from the extension, try appending a better one
171+ const contentTypeFromExtension = this . _getContentTypeFromExtension ( path )
172+ if ( contentTypeFromExtension !== contentType ) {
173+ // Some extensions fit multiple content types, so only switch if there's an improvement
174+ const newExtension = contentType in extensions ? extensions [ contentType ] [ 0 ] : 'unknown'
175+ if ( this . _types [ newExtension ] !== contentTypeFromExtension ) {
176+ path += `$.${ newExtension } `
177+ }
178+ }
179+ return path
180+ }
181+
168182 // Removes possible trailing slashes from a path
169183 _removeTrailingSlash ( path ) {
170184 return path . replace ( / \/ + $ / , '' )
0 commit comments