@@ -33,7 +33,7 @@ class ResourceMapper {
3333 this . _defaultContentType = defaultContentType
3434 this . _types = { ...types , ...overrideTypes }
3535 this . _indexFilename = indexFilename
36- this . _indexContentType = this . _getContentTypeByExtension ( indexFilename )
36+ this . _indexContentType = this . _getContentTypeFromExtension ( indexFilename )
3737
3838 // If the host needs to be replaced on every call, pre-split the root URL
3939 if ( includeHost ) {
@@ -79,7 +79,7 @@ class ResourceMapper {
7979 // Determine the URL by chopping off everything after the dollar sign
8080 const pathname = this . _removeDollarExtension ( path )
8181 const url = `${ this . resolveUrl ( hostname ) } ${ encodeURI ( pathname ) } `
82- return { url, contentType : this . _getContentTypeByExtension ( path ) }
82+ return { url, contentType : this . _getContentTypeFromExtension ( path ) }
8383 }
8484
8585 // Maps the request for a given resource and representation format to a server file
@@ -94,7 +94,7 @@ class ResourceMapper {
9494 let isFolder = filePath . endsWith ( '/' )
9595 let isIndex = searchIndex && filePath . endsWith ( '/' )
9696
97- // Create the path for a new ressource
97+ // Create the path for a new resource
9898 let path
9999 if ( createIfNotExists ) {
100100 path = filePath
@@ -106,8 +106,8 @@ class ResourceMapper {
106106 path += this . _indexFilename
107107 }
108108 // If the extension is not correct for the content type, append the correct extension
109- if ( ! isFolder && this . _getContentTypeByExtension ( path ) !== contentType ) {
110- path += `$ ${ contentType in extensions ? `. ${ extensions [ contentType ] [ 0 ] } ` : '.unknown' } `
109+ if ( ! isFolder ) {
110+ path = this . _addContentTypeExtension ( path , contentType )
111111 }
112112 // Determine the path of an existing file
113113 } else {
@@ -136,7 +136,7 @@ class ResourceMapper {
136136 }
137137 }
138138 path = `${ folder } ${ match } `
139- contentType = this . _getContentTypeByExtension ( match )
139+ contentType = this . _getContentTypeFromExtension ( match )
140140 }
141141 return { path, contentType : contentType || this . _defaultContentType }
142142 }
@@ -157,11 +157,25 @@ class ResourceMapper {
157157 }
158158
159159 // Gets the expected content type based on the extension of the path
160- _getContentTypeByExtension ( path ) {
160+ _getContentTypeFromExtension ( path ) {
161161 const extension = / \. ( [ ^ / . ] + ) $ / . exec ( path )
162162 return extension && this . _types [ extension [ 1 ] . toLowerCase ( ) ] || this . _defaultContentType
163163 }
164164
165+ // Appends an extension for the specific content type, if needed
166+ _addContentTypeExtension ( path , contentType ) {
167+ // If we would guess the wrong content type from the extension, try appending a better one
168+ const contentTypeFromExtension = this . _getContentTypeFromExtension ( path )
169+ if ( contentTypeFromExtension !== contentType ) {
170+ // Some extensions fit multiple content types, so only switch if there's an improvement
171+ const newExtension = contentType in extensions ? extensions [ contentType ] [ 0 ] : 'unknown'
172+ if ( this . _types [ newExtension ] !== contentTypeFromExtension ) {
173+ path += `$.${ newExtension } `
174+ }
175+ }
176+ return path
177+ }
178+
165179 // Removes possible trailing slashes from a path
166180 _removeTrailingSlash ( path ) {
167181 return path . replace ( / \/ + $ / , '' )
0 commit comments