Skip to content

Commit

Permalink
✨ Replace http and https with got
Browse files Browse the repository at this point in the history
closes #99

- Used [`got`](https://github.com/sindresorhus/got) for image-size requests, which is more lightweight and has the huge advantage of following redirects
- Added and updated test
- indents
  • Loading branch information
aileen committed Sep 13, 2017
1 parent 94ac029 commit 9638035
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 46 deletions.
Binary file added lib/.DS_Store
Binary file not shown.
88 changes: 51 additions & 37 deletions lib/amperize.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ var merge = require('lodash.merge')
, uuid = require('uuid')
, async = require('async')
, url = require('url')
, http = require('http')
, https = require('https')
, got = require('got')
, sizeOf = require('image-size')
, validator = require('validator')
, helpers = require('./helpers');

var DEFAULTS = {
Expand Down Expand Up @@ -170,52 +170,66 @@ Amperize.prototype.traverse = function traverse(data, html, done) {
* @return {Object} element incl. width and height
*/
function getImageSize(element) {
var options = url.parse(element.attribs.src),
timeout = 5000,
request = element.attribs.src.indexOf('https') === 0 ? https : http;
var imagePath = url.parse(element.attribs.src),
requestOptions,
timeout = 5000;

called = false;

if (!validator.isURL(imagePath.href)) {
if (called) return;
called = true;

// revert this element, do not show
element.name = 'img';

return enter();
}

// We need the user-agent, otherwise some https request may fail (e. g. cloudfare)
options.headers = { 'User-Agent': 'Mozilla/5.0' };

return request.get(options, function (response) {
var chunks = [];
response.on('data', function (chunk) {
chunks.push(chunk);
}).on('end', function () {
try {
var dimensions = sizeOf(Buffer.concat(chunks));
element.attribs.width = dimensions.width;
element.attribs.height = dimensions.height;

return getLayoutAttribute(element);
} catch (err) {
if (called) return;
called = true;

// revert this element, do not show
element.name = 'img';
return enter();
requestOptions = {
headers: {
'User-Agent': 'Mozilla/5.0'
},
timeout: timeout,
encoding: null
};

return got (
imagePath.href,
requestOptions
).then(function (response) {
try {
// Using the Buffer rather than an URL requires to use sizeOf synchronously.
// See https://github.com/image-size/image-size#asynchronous
var dimensions = sizeOf(response.body);

// CASE: `.ico` files might have multiple images and therefore multiple sizes.
// We return the largest size found (image-size default is the first size found)
if (dimensions.images) {
dimensions.width = _.maxBy(dimensions.images, function (w) {return w.width;}).width;
dimensions.height = _.maxBy(dimensions.images, function (h) {return h.height;}).height;
}
});
}).on('socket', function (socket) {
socket.setTimeout(timeout);
socket.on('timeout', function () {

element.attribs.width = dimensions.width;
element.attribs.height = dimensions.height;

return getLayoutAttribute(element);
} catch (err) {
if (called) return;
called = true;

// revert this element, do not show
element.name = 'img';
return enter();
});
}).on('error', function () {
if (called) return;
called = true;

// revert this element, do not show
element.name = 'img';
return enter();
}
}).catch(function (err) {
if (called) return;
called = true;

// revert this element, do not show
element.name = 'img';
return enter();
});
}

Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@
"dependencies": {
"async": "2.1.4",
"emits": "3.0.0",
"got": "7.1.0",
"htmlparser2": "3.9.2",
"image-size": "0.5.1",
"lodash.merge": "4.6.0",
"nock": "^9.0.2",
"rewire": "^2.5.2",
"uuid": "^3.0.0"
"uuid": "^3.0.0",
"validator": "8.2.0"
},
"devDependencies": {
"chai": "3.5.0",
Expand Down
57 changes: 49 additions & 8 deletions test/amperize.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ describe('Amperize', function () {

afterEach(function () {
sinon.restore();
Amperize.__set__('called', false);
});

it('throws an error if no callback provided', function () {
Expand All @@ -95,7 +96,7 @@ describe('Amperize', function () {
sizeOfMock = nock('http://static.wixstatic.com')
.get('/media/355241_d31358572a2542c5a44738ddcb59e7ea.jpg_256')
.reply(200, {
data: '<Buffer 2c be a4 40 f7 87 73 1e 57 2c c1 e4 0d 79 03 95 42 f0 42 2e 41 95 27 c9 5c 35 a7 71 2c 09 5a 57 d3 04 1e 83 03 28 07 96 b0 c8 88 65 07 7a d1 d6 63 50>'
body: '<Buffer 2c be a4 40 f7 87 73 1e 57 2c c1 e4 0d 79 03 95 42 f0 42 2e 41 95 27 c9 5c 35 a7 71 2c 09 5a 57 d3 04 1e 83 03 28 07 96 b0 c8 88 65 07 7a d1 d6 63 50>'
});

sizeOfStub.returns({width: 50, height: 50, type: 'jpg'});
Expand All @@ -118,7 +119,7 @@ describe('Amperize', function () {
sizeOfMock = nock('http://static.wixstatic.com')
.get('/media/355241_d31358572a2542c5a44738ddcb59e7ea.jpg_256')
.reply(200, {
data: '<Buffer 2c be a4 40 f7 87 73 1e 57 2c c1 e4 0d 79 03 95 42 f0 42 2e 41 95 27 c9 5c 35 a7 71 2c 09 5a 57 d3 04 1e 83 03 28 07 96 b0 c8 88 65 07 7a d1 d6 63 50>'
body: '<Buffer 2c be a4 40 f7 87 73 1e 57 2c c1 e4 0d 79 03 95 42 f0 42 2e 41 95 27 c9 5c 35 a7 71 2c 09 5a 57 d3 04 1e 83 03 28 07 96 b0 c8 88 65 07 7a d1 d6 63 50>'
});

sizeOfStub.returns({width: 350, height: 200, type: 'jpg'});
Expand All @@ -141,7 +142,7 @@ describe('Amperize', function () {
sizeOfMock = nock('https://media.giphy.com')
.get('/media/l46CtzgjhTm29Cbjq/giphy.gif')
.reply(200, {
data: '<Buffer 2c be a4 40 f7 87 73 1e 57 2c c1 e4 0d 79 03 95 42 f0 42 2e 41 95 27 c9 5c 35 a7 71 2c 09 5a 57 d3 04 1e 83 03 28 07 96 b0 c8 88 65 07 7a d1 d6 63 50>'
body: '<Buffer 2c be a4 40 f7 87 73 1e 57 2c c1 e4 0d 79 03 95 42 f0 42 2e 41 95 27 c9 5c 35 a7 71 2c 09 5a 57 d3 04 1e 83 03 28 07 96 b0 c8 88 65 07 7a d1 d6 63 50>'
});

sizeOfStub.returns({width: 800, height: 600, type: 'gif'});
Expand Down Expand Up @@ -230,6 +231,15 @@ describe('Amperize', function () {
});
});

it('can handle invalid URLs', function (done) {
amperize.parse('<img src="http:not-a-website">', function (error, result) {
expect(result).to.exist;
expect(Amperize.__get__('called')).to.be.equal(true);
expect(result).to.be.equal('<img src="http:not-a-website">');
done();
});
});

it('can handle <iframe> tag without src and does not transform it', function (done) {
amperize.parse('<iframe>', function (error, result) {
expect(result).to.exist;
Expand Down Expand Up @@ -274,11 +284,42 @@ describe('Amperize', function () {
});
});

it('can handle redirects', function (done) {
var secondSizeOfMock;

sizeOfMock = nock('http://noimagehere.com')
.get('/files/f/feedough/x/11/1540353_20925115.jpg')
.reply(301, {
body: '<Buffer 2c be a4 40 f7 87 73 1e 57 2c c1 e4 0d 79 03 95 42 f0 42 2e 41 95 27 c9 5c 35 a7 71 2c 09 5a 57 d3 04 1e 83 03 28 07 96 b0 c8 88 65 07 7a d1 d6 63 50>'
},
{
location: 'http://someredirectedurl.com/files/f/feedough/x/11/1540353_20925115.jpg'
});

secondSizeOfMock = nock('http://someredirectedurl.com')
.get('/files/f/feedough/x/11/1540353_20925115.jpg')
.reply(200, {
body: '<Buffer 2c be a4 40 f7 87 73 1e 57 2c c1 e4 0d 79 03 95 42 f0 42 2e 41 95 27 c9 5c 35 a7 71 2c 09 5a 57 d3 04 1e 83 03 28 07 96 b0 c8 88 65 07 7a d1 d6 63 50>'
});

sizeOfStub.returns({width: 100, height: 100, type: 'jpg'});
Amperize.__set__('sizeOf', sizeOfStub);


amperize.parse('<img src="http://noimagehere.com/files/f/feedough/x/11/1540353_20925115.jpg">', function (error, result) {
expect(sizeOfMock.isDone()).to.be.equal(true);
expect(secondSizeOfMock.isDone()).to.be.equal(true);
expect(Amperize.__get__('called')).to.be.equal(false);
expect(error).to.be.null;
expect(result).to.contain('<amp-img src="http://noimagehere.com/files/f/feedough/x/11/1540353_20925115.jpg" width="100" height="100" layout="fixed"></amp-img>');
done();
});
});

it('can handle request errors', function (done) {
var callCounts;
sizeOfMock = nock('http://example.com')
.get('/images/IMG_xyz.jpg')
.replyWithError('something awful happened');
.reply(404, {message: 'something awful happened', code: 'AWFUL_ERROR'});

amperize.parse('<img src="http://example.com/images/IMG_xyz.jpg">', function (error, result) {
expect(Amperize.__get__('called')).to.be.equal(true);
Expand All @@ -292,9 +333,9 @@ describe('Amperize', function () {
sizeOfMock = nock('http://example.com')
.get('/images/IMG_xyz.jpg')
.reply(200, {
data: '<Buffer 2c be a4 40 f7 87 73 1e 57 2c c1 e4 0d 79 03 95 42 f0 42 2e 41 95 27 c9 5c 35 a7 71 2c 09 5a 57 d3 04 1e 83 03 28 07 96 b0 c8 88 65 07 7a d1 d6 63 50>'
body: '<Buffer 2c be a4 40 f7 87 73 1e 57 2c c1 e4 0d 79 03 95 42 f0 42 2e 41 95 27 c9 5c 35 a7 71 2c 09 5a 57 d3 04 1e 83 03 28 07 96 b0 c8 88 65 07 7a d1 d6 63 50>'
});
sizeOfStub.throws('error');
sizeOfStub.throws({error: 'image-size could not find dimensions'});
Amperize.__set__('sizeOf', sizeOfStub);

amperize.parse('<img src="http://example.com/images/IMG_xyz.jpg">', function (error, result) {
Expand All @@ -310,7 +351,7 @@ describe('Amperize', function () {
.get('/images/IMG_xyz.jpg')
.socketDelay(5500)
.reply(200, {
data: '<Buffer 2c be a4 40 f7 87 73 1e 57 2c c1 e4 0d 79 03 95 42 f0 42 2e 41 95 27 c9 5c 35 a7 71 2c 09 5a 57 d3 04 1e 83 03 28 07 96 b0 c8 88 65 07 7a d1 d6 63 50>'
body: '<Buffer 2c be a4 40 f7 87 73 1e 57 2c c1 e4 0d 79 03 95 42 f0 42 2e 41 95 27 c9 5c 35 a7 71 2c 09 5a 57 d3 04 1e 83 03 28 07 96 b0 c8 88 65 07 7a d1 d6 63 50>'
});

amperize.parse('<img src="http://example.com/images/IMG_xyz.jpg">', function (error, result) {
Expand Down

0 comments on commit 9638035

Please sign in to comment.