Skip to content

Commit 55be05f

Browse files
author
jaxoncreed
committed
Merge branch 'dev' of https://github.com/solid/node-solid-server into fix/1317
2 parents a898f5e + 1ff9728 commit 55be05f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+1771
-251
lines changed

lib/ldp.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ class LDP {
158158

159159
// HACK: the middleware in webid-oidc.js uses body-parser, thus ending the stream of data
160160
// for JSON bodies. So, the stream needs to be reset
161-
if (contentType.includes('application/json')) {
161+
if (contentType && contentType.includes('application/json')) {
162162
stream = intoStream(JSON.stringify(stream.body))
163163
}
164164

lib/resource-mapper.js

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const { promisify } = require('util')
44
const { types, extensions } = require('mime-types')
55
const readdir = promisify(fs.readdir)
66
const HTTPError = require('./http-error')
7+
const pathUtil = require('path')
78

89
/*
910
* A ResourceMapper maintains the mapping between HTTP URLs and server filenames,
@@ -33,7 +34,7 @@ class ResourceMapper {
3334
this._defaultContentType = defaultContentType
3435
this._types = { ...types, ...overrideTypes }
3536
this._indexFilename = indexFilename
36-
this._indexContentType = this._getContentTypeByExtension(indexFilename)
37+
this._indexContentType = this._getContentTypeFromExtension(indexFilename)
3738

3839
// If the host needs to be replaced on every call, pre-split the root URL
3940
if (includeHost) {
@@ -78,8 +79,10 @@ class ResourceMapper {
7879

7980
// Determine the URL by chopping off everything after the dollar sign
8081
const pathname = this._removeDollarExtension(path)
81-
const url = `${this.resolveUrl(hostname)}${encodeURI(pathname)}`
82-
return { url, contentType: this._getContentTypeByExtension(path) }
82+
const url = `${this.resolveUrl(hostname)}${
83+
pathname.split(pathUtil.sep).map((component) => encodeURIComponent(component)).join('/')
84+
}`
85+
return { url, contentType: this._getContentTypeFromExtension(path) }
8386
}
8487

8588
// Maps the request for a given resource and representation format to a server file
@@ -94,7 +97,7 @@ class ResourceMapper {
9497
let isFolder = filePath.endsWith('/')
9598
let isIndex = searchIndex && filePath.endsWith('/')
9699

97-
// Create the path for a new ressource
100+
// Create the path for a new resource
98101
let path
99102
if (createIfNotExists) {
100103
path = filePath
@@ -106,8 +109,8 @@ class ResourceMapper {
106109
path += this._indexFilename
107110
}
108111
// 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'}`
112+
if (!isFolder) {
113+
path = this._addContentTypeExtension(path, contentType)
111114
}
112115
// Determine the path of an existing file
113116
} else {
@@ -136,7 +139,7 @@ class ResourceMapper {
136139
}
137140
}
138141
path = `${folder}${match}`
139-
contentType = this._getContentTypeByExtension(match)
142+
contentType = this._getContentTypeFromExtension(match)
140143
}
141144
return { path, contentType: contentType || this._defaultContentType }
142145
}
@@ -157,11 +160,25 @@ class ResourceMapper {
157160
}
158161

159162
// Gets the expected content type based on the extension of the path
160-
_getContentTypeByExtension (path) {
163+
_getContentTypeFromExtension (path) {
161164
const extension = /\.([^/.]+)$/.exec(path)
162165
return extension && this._types[extension[1].toLowerCase()] || this._defaultContentType
163166
}
164167

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+
165182
// Removes possible trailing slashes from a path
166183
_removeTrailingSlash (path) {
167184
return path.replace(/\/+$/, '')

0 commit comments

Comments
 (0)