Skip to content

Commit b2a18e3

Browse files
authored
Decode url-based filenames (#175)
* Decode url-based filenames * Update tests
1 parent 08a36e0 commit b2a18e3

File tree

4 files changed

+59
-18
lines changed

4 files changed

+59
-18
lines changed

lib/utils.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,25 @@ function getRelativePath (path1, path2) {
3535
return getUnixPath(relativePath);
3636
}
3737

38+
/**
39+
* Returns decoded pathname from url
40+
* Example: https://example.co/path/logo%20(1).svg => /path/logo (1).svg
41+
* @param u - url
42+
* @returns {string} decoded pathname
43+
*/
44+
function getPathnameFromUrl (u) {
45+
var pathname = url.parse(u).pathname;
46+
return decodeURI(pathname);
47+
}
48+
3849
/**
3950
* Returns filename from given url
4051
* Example: http://example.com/some/path/file.js => file.js
4152
* @param {string} u - url
4253
* @returns {string} filename
4354
*/
4455
function getFilenameFromUrl (u) {
45-
return path.basename(url.parse(u).pathname);
56+
return path.basename(getPathnameFromUrl(u));
4657
}
4758

4859
/**
@@ -52,8 +63,8 @@ function getFilenameFromUrl (u) {
5263
* @returns {string} path
5364
*/
5465
function getFilepathFromUrl (u) {
55-
var normalizedUrl = normalizeUrl(u);
56-
return url.parse(normalizedUrl).pathname.substring(1);
66+
var nu = normalizeUrl(u);
67+
return getPathnameFromUrl(nu).substring(1);
5768
}
5869

5970
function getHashFromUrl (u) {

test/unit/filename-generator/by-site-structure-test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,14 @@ describe('FilenameGenerator: bySiteStructure', function() {
7070
var filename = _.last(filepath.split('/'));
7171
should(filename.length).be.lessThan(255);
7272
});
73+
74+
it('should return decoded filepath', function() {
75+
var r = new Resource('https://developer.mozilla.org/ru/docs/JavaScript_%D1%88%D0%B5%D0%BB%D0%BB%D1%8B');
76+
var filename = bySiteStructureFilenameGenerator(r, options);
77+
filename.should.equalFileSystemPath('ru/docs/JavaScript_шеллы');
78+
79+
var r2 = new Resource('https://developer.mozilla.org/Hello%20G%C3%BCnter.png');
80+
var filename2 = bySiteStructureFilenameGenerator(r2, options);
81+
filename2.should.equalFileSystemPath('Hello Günter.png');
82+
});
7383
});

test/unit/filename-generator/by-type-test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,14 @@ describe('FilenameGenerator: byType', function() {
111111

112112
should(f2).not.be.eql(f1);
113113
});
114+
115+
it('should return decoded url-based filename', function() {
116+
var r = new Resource('https://developer.mozilla.org/ru/docs/JavaScript_%D1%88%D0%B5%D0%BB%D0%BB%D1%8B');
117+
var filename = byTypeFilenameGenerator(r, {}, []);
118+
filename.should.equalFileSystemPath('JavaScript_шеллы');
119+
120+
var r2 = new Resource('https://developer.mozilla.org/Hello%20G%C3%BCnter.png');
121+
var filename2 = byTypeFilenameGenerator(r2, {}, []);
122+
filename2.should.equalFileSystemPath('Hello Günter.png');
123+
});
114124
});

test/unit/utils-test.js

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -48,28 +48,31 @@ describe('Utils', function () {
4848

4949
describe('#getFilenameFromUrl(url)', function () {
5050
it('should return last path item as filename & trim all after first ? or #', function () {
51-
utils.getFilenameFromUrl('http://example.com/index.html').should.equalFileSystemPath('index.html');
52-
utils.getFilenameFromUrl('http://example.com/p/a/t/h/index.html').should.equalFileSystemPath('index.html');
53-
utils.getFilenameFromUrl('http://example.com/index.html?12').should.equalFileSystemPath('index.html');
54-
utils.getFilenameFromUrl('http://example.com/index.html#t?12').should.equalFileSystemPath('index.html');
55-
utils.getFilenameFromUrl('http://example.com/index.html?12#t').should.equalFileSystemPath('index.html');
56-
utils.getFilenameFromUrl('http://example.com/?12_jdlsk').should.be.empty();
57-
utils.getFilenameFromUrl('http://example.com/#index.html').should.be.empty();
58-
utils.getFilenameFromUrl('http://example.com/').should.be.empty();
51+
utils.getFilenameFromUrl('http://example.com/index.html').should.equal('index.html');
52+
utils.getFilenameFromUrl('http://example.com/p/a/t/h/index.html').should.equal('index.html');
53+
utils.getFilenameFromUrl('http://example.com/index.html?12').should.equal('index.html');
54+
utils.getFilenameFromUrl('http://example.com/index.html#t?12').should.equal('index.html');
55+
utils.getFilenameFromUrl('http://example.com/index.html?12#t').should.equal('index.html');
56+
utils.getFilenameFromUrl('http://example.com/?12_jdlsk').should.equal('');
57+
utils.getFilenameFromUrl('http://example.com/#index.html').should.equal('');
58+
utils.getFilenameFromUrl('http://example.com/').should.equal('');
5959
});
6060
it('should return unconverted filename if there are no ?,#', function () {
61-
utils.getFilenameFromUrl('index.html').should.equalFileSystemPath('index.html');
61+
utils.getFilenameFromUrl('index.html').should.equal('index.html');
62+
});
63+
it('should decode escaped chars', function () {
64+
utils.getFilenameFromUrl('https://example.co/logo-mobile%20(1).svg?q=650').should.equal('logo-mobile (1).svg');
6265
});
6366
});
6467

6568
describe('#getFilepathFromUrl', function () {
6669
it('should return empty sting if url has no pathname', function() {
67-
utils.getFilepathFromUrl('http://example.com').should.be.empty();
68-
utils.getFilepathFromUrl('http://example.com/').should.be.empty();
69-
utils.getFilepathFromUrl('http://example.com?').should.be.empty();
70-
utils.getFilepathFromUrl('http://example.com?abc=3').should.be.empty();
71-
utils.getFilepathFromUrl('http://example.com#').should.be.empty();
72-
utils.getFilepathFromUrl('http://example.com#test').should.be.empty();
70+
utils.getFilepathFromUrl('http://example.com').should.equal('');
71+
utils.getFilepathFromUrl('http://example.com/').should.equal('');
72+
utils.getFilepathFromUrl('http://example.com?').should.equal('');
73+
utils.getFilepathFromUrl('http://example.com?abc=3').should.equal('');
74+
utils.getFilepathFromUrl('http://example.com#').should.equal('');
75+
utils.getFilepathFromUrl('http://example.com#test').should.equal('');
7376
});
7477
it('should return path if url has pathname', function() {
7578
utils.getFilepathFromUrl('http://example.com/some/path').should.equal('some/path');
@@ -81,6 +84,13 @@ describe('Utils', function () {
8184
utils.getFilepathFromUrl('http://example.com/some/path/').should.equal('some/path');
8285
utils.getFilepathFromUrl('http://example.com/some/path/file.css/').should.equal('some/path/file.css');
8386
});
87+
it('should normalize slashes', function() {
88+
utils.getFilepathFromUrl('http://example.com///some//path').should.equal('some/path');
89+
utils.getFilepathFromUrl('http://example.com//////////file.css/').should.equal('file.css');
90+
});
91+
it('should decode escaped chars', function () {
92+
utils.getFilepathFromUrl('https://example.co/logo/logo-mobile%20(1).svg?q=650').should.equal('logo/logo-mobile (1).svg');
93+
});
8494
});
8595

8696
describe('#getHashFromUrl', function () {

0 commit comments

Comments
 (0)