diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3eda792 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 diff --git a/index.js b/index.js index 167e9d4..032903f 100644 --- a/index.js +++ b/index.js @@ -199,7 +199,14 @@ module.exports = function markdownLinkCheck(markdown, opts, callback) { return; } + let numCalls = 0; linkCheck(link, opts, function (err, result) { + if (numCalls > 0) { + console.trace(`linkCheck called us back more than once for ${link}. This is likely due to a server answering HEAD with 302 and a body, against the HTTP spec. Ignoring.`); + return; + } + numCalls += 1; + if (opts.showProgressBar) { bar.tick(); } diff --git a/test/markdown-link-check.test.js b/test/markdown-link-check.test.js index a2a72c1..10572bf 100644 --- a/test/markdown-link-check.test.js +++ b/test/markdown-link-check.test.js @@ -53,6 +53,22 @@ describe('markdown-link-check', function () { res.json({foo:'bar'}); }); + app.use('/redirect-with-body-in-head', function (req, res) { + /* Don't judge me. I found at least one server on the + * Internet doing this and it triggered a bug. */ + const body = 'Let me send you a body, although you only asked for a HEAD.'; + + const headers = + 'HTTP/1.1 302 Found\r\n' + + 'Connection: close\r\n' + + 'Location: /foo/bar\r\n' + + `Content-Length: ${Buffer.byteLength(body)}\r\n` + + '\r\n'; + + res.socket.write(headers + body); + res.socket.destroy(); + }); + app.get('/basic-auth', function (req, res) { if (req.headers["authorization"] === "Basic Zm9vOmJhcg==") { res.sendStatus(200); @@ -110,6 +126,9 @@ describe('markdown-link-check', function () { expect(results).to.be.an('array'); const expected = [ + // redirect-with-body-in-head + { statusCode: 200, status: 'alive' }, + // redirect-loop { statusCode: 0, status: 'dead' }, diff --git a/test/sample.md b/test/sample.md index 830803f..42f13e8 100644 --- a/test/sample.md +++ b/test/sample.md @@ -2,6 +2,7 @@ This is a test file: +* [redirect-with-body-in-head](%%BASE_URL%%/redirect-with-body-in-head) (alive) * [redirect-loop](%%BASE_URL%%/loop) (dead) * [valid](%%BASE_URL%%/foo/bar) (alive) * [invalid](%%BASE_URL%%/foo/dead) (dead)