encodeURI vs. encodeURIComponent
yomybaby opened this issue · comments
Hi,
I have a question.
Is there any reason to use encodeURIComponent
instead of encodeURI
in getFileLocation()
?
https://github.com/parse-community/parse-server-s3-adapter/blob/master/index.js#L129
This encodes objectKey. objectKey can have /
character. (eg. w200/myImg.png
).
encodeURIComponent
encodes /
to %2F
.
encodeURI
does NOT encode /
.
If I had to take a guess its because encodeURIComponent
handles reserve characters ;,/?:@&=+$#
.
This is encouraged by AWS best practices (see the “Characters That Might Require Special Handling” section.
Do you have a specific file / uri that is causing an issue?
Take a look at this stack overflow question:
encodeURI assumes that the input is a complete URI that might have some characters which need encoding in it.
encodeURIComponent will encode everything with special meaning, so you use it for components of URIs such as
In this case, we are encoding an URI's component, so encodeURIComponent
should be more appropriate as a file with '/' in it's name should have this character encoded as well. Otherwise it would be understood as another path.
Please look ..
- S3 object key can have
/
characters (my/file/is/here.png
, s3 bucket / make a folder ) - Default filename validator doesn't allow
/
in the file name. So it could uplod a file which has '/' character in file name. - If some file
my/file/is/here.png
is already existed in S3 bucket, it can be pointed by file fields.
curl -X "POST" "http://localhost:1337/parse/classes/Test" \
-H 'X-Parse-Application-Id: my.app.id' \
-H 'Content-Type: text/plain' \
-d $'{
"myFile": {
"name": "my/file/is/here.png",
"url": "my/file/is/here.png",
"__type": "File"
}
}'
It can fetched :
curl "http://localhost:1337/parse/classes/Test" \
-H 'X-Parse-Application-Id: my.app.id' \
# result
{
"results": [
{
"objectId": "X7ylThRwrT",
"createdAt": "2019-10-28T09:56:03.240Z",
"updatedAt": "2019-10-28T09:56:03.240Z",
"myFile": {
"__type": "File",
"name": "my/file/is/here.png",
"url": "https://s3.ap-northeast-2.amazonaws.com/dev-image.mojitok.com/my%2Ffile%2Fis%2Fhere.png"
}
}
]
}
Look this part my%2Ffile%2Fis%2Fhere.png
. my/file/is/here.png
is better than my%2Ffile%2Fis%2Fhere.png
. /
should not be encoded.
There is no reason to escape / to %2F
.
https://github.com/parse-community/parse-server-s3-adapter/blob/master/index.js#L129
// current
const fileName = encodeURIComponent(filename);
// should be
const fileName = filename.split('/').map(encodeURIComponent).join('/');
What do you think about this issue?
You just need to add my/file/is/
to your bucketPrefix
option.
I know bucketPrefix option. :) I explained when prefix is not fixed.
For example,
- Upload “my.png” using File Api. S3 object key is “o27gs83sgdbgj_my.png”
- S3 event triggers AWS Lambda function to make thumbnails. It generates files to S3 directly.
“200x200/o27gs83sgdbgj_my.png”
“100x100/o27gs83sgdbgj_my.png”
There is no way to handle this.
I found similar issue and PR.
My vote would be to just use encodeURL, but I'm adding @yomybaby's suggestion to the PR that's now handling directories.
TFW: Amazon ignores their own recommendations: https://images-na.ssl-images-amazon.com/images/I/41l1%2BOPTfKL.jpg