Merge pull request #3557 from thelounge/xpaw/premature-close

Fix "premature close" on link previews
This commit is contained in:
Pavel Djundik 2019-12-14 22:45:49 +02:00 committed by GitHub
commit 0486f43f9f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -330,31 +330,32 @@ function fetch(uri, headers) {
promise = new Promise((resolve, reject) => { promise = new Promise((resolve, reject) => {
let buffer = Buffer.from(""); let buffer = Buffer.from("");
let request; let contentLength = 0;
let response; let contentType;
let limit = Helper.config.prefetchMaxImageSize * 1024; let limit = Helper.config.prefetchMaxImageSize * 1024;
try { try {
got.stream(uri, { const gotStream = got.stream(uri, {
retry: 0,
timeout: 5000, timeout: 5000,
headers: getRequestHeaders(headers), headers: getRequestHeaders(headers),
rejectUnauthorized: false, rejectUnauthorized: false,
}) });
.on("request", (req) => (request = req))
.on("response", function(res) {
response = res;
if (imageTypeRegex.test(res.headers["content-type"])) { gotStream
.on("response", function(res) {
contentLength = parseInt(res.headers["content-length"], 10) || 0;
contentType = res.headers["content-type"];
if (imageTypeRegex.test(contentType)) {
// response is an image // response is an image
// if Content-Length header reports a size exceeding the prefetch limit, abort fetch // if Content-Length header reports a size exceeding the prefetch limit, abort fetch
const contentLength = parseInt(res.headers["content-length"], 10) || 0;
if (contentLength > limit) { if (contentLength > limit) {
request.abort(); gotStream.destroy();
} }
} else if (mediaTypeRegex.test(res.headers["content-type"])) { } else if (mediaTypeRegex.test(contentType)) {
// We don't need to download the file any further after we received content-type header // We don't need to download the file any further after we received content-type header
request.abort(); gotStream.destroy();
} else { } else {
// if not image, limit download to 50kb, since we need only meta tags // if not image, limit download to 50kb, since we need only meta tags
// twitter.com sends opengraph meta tags within ~20kb of data for individual tweets // twitter.com sends opengraph meta tags within ~20kb of data for individual tweets
@ -366,19 +367,18 @@ function fetch(uri, headers) {
buffer = Buffer.concat([buffer, data], buffer.length + data.length); buffer = Buffer.concat([buffer, data], buffer.length + data.length);
if (buffer.length >= limit) { if (buffer.length >= limit) {
request.abort(); gotStream.destroy();
} }
}) })
.on("end", () => { .on("end", () => gotStream.destroy())
.on("close", () => {
let type = ""; let type = "";
let size = parseInt(response.headers["content-length"], 10) || buffer.length;
if (size < buffer.length) { // If we downloaded more data then specified in Content-Length, use real data size
size = buffer.length; const size = contentLength > buffer.length ? contentLength : buffer.length;
}
if (response.headers["content-type"]) { if (contentType) {
type = response.headers["content-type"].split(/ *; */).shift(); type = contentType.split(/ *; */).shift();
} }
resolve({data: buffer, type, size}); resolve({data: buffer, type, size});