1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-01-17 18:44:45 +02:00

Desktop: Fixes #3986: Handle gzipped CSS files when importing from clipper

This commit is contained in:
Laurent Cozic 2020-10-28 15:47:36 +00:00
parent 04cfd07176
commit ece7ffadd6
2 changed files with 71 additions and 8 deletions

View File

@ -13,6 +13,43 @@ const http = require('http');
const https = require('https');
const toRelative = require('relative');
const timers = require('timers');
const zlib = require('zlib');
function fileExists(filePath) {
try {
return fs.statSync(filePath).isFile();
} catch (err) {
return false;
}
}
const gunzipFile = function(source, destination) {
if (!fileExists(source)) {
throw new Error(`No such file: ${source}`);
}
return new Promise((resolve, reject) => {
// prepare streams
const src = fs.createReadStream(source);
const dest = fs.createWriteStream(destination);
// extract the archive
src.pipe(zlib.createGunzip()).pipe(dest);
// callback on extract completion
dest.on('close', function() {
resolve();
});
src.on('error', () => {
reject();
});
dest.on('error', () => {
reject();
});
});
};
function shimInit() {
shim.fsDriver = () => {
@ -365,9 +402,25 @@ function shimInit() {
const request = http.request(requestOptions, function(response) {
response.pipe(file);
const isGzipped = response.headers['content-encoding'] === 'gzip';
file.on('finish', function() {
file.close(() => {
resolve(makeResponse(response));
file.close(async () => {
if (isGzipped) {
const gzipFilePath = `${filePath}.gzip`;
await shim.fsDriver().move(filePath, gzipFilePath);
try {
await gunzipFile(gzipFilePath, filePath);
resolve(makeResponse(response));
} catch (error) {
cleanUpOnError(error);
}
shim.fsDriver().remove(gzipFilePath);
} else {
resolve(makeResponse(response));
}
});
});
});

View File

@ -36,21 +36,31 @@ function shimInit() {
};
shim.fetch = async function(url, options = null) {
// The native fetch() throws an uncatable error that crashes the app if calling it with an
// invalid URL such as '//.resource' or "http://ocloud. de" so detect if the URL is valid beforehand
// and throw a catchable error.
// Bug: https://github.com/facebook/react-native/issues/7436
// The native fetch() throws an uncatchable error that crashes the
// app if calling it with an invalid URL such as '//.resource' or
// "http://ocloud. de" so detect if the URL is valid beforehand and
// throw a catchable error. Bug:
// https://github.com/facebook/react-native/issues/7436
const validatedUrl = urlValidator.isUri(url);
if (!validatedUrl) throw new Error(`Not a valid URL: ${url}`);
return shim.fetchWithRetry(() => {
// If the request has a body and it's not a GET call, and it doesn't have a Content-Type header
// we display a warning, because it could trigger a "Network request failed" error.
// If the request has a body and it's not a GET call, and it
// doesn't have a Content-Type header we display a warning,
// because it could trigger a "Network request failed" error.
// https://github.com/facebook/react-native/issues/30176
if (options?.body && options?.method && options.method !== 'GET' && !options?.headers?.['Content-Type']) {
console.warn('Done a non-GET fetch call without a Content-Type header. It may make the request fail.', url, options);
}
// Among React Native `fetch()` many bugs, one of them is that
// it will truncate strings when they contain binary data.
// Browser fetch() or Node fetch() work fine but as always RN's
// one doesn't. There's no obvious way to fix this so we'll
// have to wait if it's eventually fixed upstream. See here for
// more info:
// https://github.com/laurent22/joplin/issues/3986#issuecomment-718019688
return fetch(validatedUrl, options);
}, options);
};