Поправки для поддержки reverse-proxy, рефакторинг
This commit is contained in:
@@ -1,3 +1,7 @@
|
|||||||
import WebSocketConnection from '../../../server/core/WebSocketConnection';
|
import WebSocketConnection from '../../../server/core/WebSocketConnection';
|
||||||
|
|
||||||
export default new WebSocketConnection();
|
const protocol = (window.location.protocol == 'https:' ? 'wss:' : 'ws:');
|
||||||
|
let url = `${protocol}//${window.location.host}${window.location.pathname}`;
|
||||||
|
url += (url[url.length - 1] === '/' ? 'ws' : '/ws');
|
||||||
|
|
||||||
|
export default new WebSocketConnection(url);
|
||||||
@@ -68,7 +68,8 @@ class RemoteLib {
|
|||||||
|
|
||||||
const buf = await this.down.load(`${this.remoteHost}${link}`, {decompress: false});
|
const buf = await this.down.load(`${this.remoteHost}${link}`, {decompress: false});
|
||||||
|
|
||||||
const publicPath = `${this.config.publicFilesDir}${link}`;
|
const hash = path.basename(link);
|
||||||
|
const publicPath = `${this.config.bookDir}/${hash}`;
|
||||||
|
|
||||||
await fs.writeFile(publicPath, buf);
|
await fs.writeFile(publicPath, buf);
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class WebWorker {
|
|||||||
|
|
||||||
const dirConfig = [
|
const dirConfig = [
|
||||||
{
|
{
|
||||||
dir: config.filesDir,
|
dir: config.bookDir,
|
||||||
maxSize: config.maxFilesDirSize,
|
maxSize: config.maxFilesDirSize,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -380,8 +380,8 @@ class WebWorker {
|
|||||||
hash = await this.remoteLib.downloadBook(bookUid);
|
hash = await this.remoteLib.downloadBook(bookUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
const link = `${this.config.filesPathStatic}/${hash}`;
|
const link = `${this.config.bookPathStatic}/${hash}`;
|
||||||
const bookFile = `${this.config.filesDir}/${hash}`;
|
const bookFile = `${this.config.bookDir}/${hash}`;
|
||||||
const bookFileDesc = `${bookFile}.d.json`;
|
const bookFileDesc = `${bookFile}.d.json`;
|
||||||
|
|
||||||
if (!await fs.pathExists(bookFile) || !await fs.pathExists(bookFileDesc)) {
|
if (!await fs.pathExists(bookFile) || !await fs.pathExists(bookFileDesc)) {
|
||||||
@@ -447,11 +447,11 @@ class WebWorker {
|
|||||||
rows = await db.select({table: 'file_hash', where: `@@id(${db.esc(bookPath)})`});
|
rows = await db.select({table: 'file_hash', where: `@@id(${db.esc(bookPath)})`});
|
||||||
if (rows.length) {//хеш найден по bookPath
|
if (rows.length) {//хеш найден по bookPath
|
||||||
const hash = rows[0].hash;
|
const hash = rows[0].hash;
|
||||||
const bookFile = `${this.config.filesDir}/${hash}`;
|
const bookFile = `${this.config.bookDir}/${hash}`;
|
||||||
const bookFileDesc = `${bookFile}.d.json`;
|
const bookFileDesc = `${bookFile}.d.json`;
|
||||||
|
|
||||||
if (await fs.pathExists(bookFile) && await fs.pathExists(bookFileDesc)) {
|
if (await fs.pathExists(bookFile) && await fs.pathExists(bookFileDesc)) {
|
||||||
link = `${this.config.filesPathStatic}/${hash}`;
|
link = `${this.config.bookPathStatic}/${hash}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,7 +479,7 @@ class WebWorker {
|
|||||||
|
|
||||||
let bookInfo = await this.getBookLink(bookUid);
|
let bookInfo = await this.getBookLink(bookUid);
|
||||||
const hash = path.basename(bookInfo.link);
|
const hash = path.basename(bookInfo.link);
|
||||||
const bookFile = `${this.config.filesDir}/${hash}`;
|
const bookFile = `${this.config.bookDir}/${hash}`;
|
||||||
const bookFileInfo = `${bookFile}.i.json`;
|
const bookFileInfo = `${bookFile}.i.json`;
|
||||||
|
|
||||||
let rows = await db.select({table: 'book', where: `@@hash('_uid', ${db.esc(bookUid)})`});
|
let rows = await db.select({table: 'book', where: `@@hash('_uid', ${db.esc(bookUid)})`});
|
||||||
@@ -501,7 +501,7 @@ class WebWorker {
|
|||||||
result.fb2 = fb2.rawNodes;
|
result.fb2 = fb2.rawNodes;
|
||||||
|
|
||||||
if (cover) {
|
if (cover) {
|
||||||
result.cover = `${this.config.filesPathStatic}/${hash}${coverExt}`;
|
result.cover = `${this.config.bookPathStatic}/${hash}${coverExt}`;
|
||||||
await fs.writeFile(`${bookFile}${coverExt}`, cover);
|
await fs.writeFile(`${bookFile}${coverExt}`, cover);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ module.exports = async(config) => {
|
|||||||
|
|
||||||
if (await fs.pathExists(verFile)) {
|
if (await fs.pathExists(verFile)) {
|
||||||
const curPublicVersion = await fs.readFile(verFile, 'utf8');
|
const curPublicVersion = await fs.readFile(verFile, 'utf8');
|
||||||
if (curPublicVersion == config.version)
|
if (curPublicVersion == config.version + config.rootPathStatic)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,6 +26,6 @@ module.exports = async(config) => {
|
|||||||
await zipReader.close();
|
await zipReader.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
await fs.writeFile(verFile, config.version);
|
await fs.writeFile(verFile, config.version + config.rootPathStatic);
|
||||||
await fs.remove(zipFile);
|
await fs.remove(zipFile);
|
||||||
};
|
};
|
||||||
@@ -50,13 +50,14 @@ async function init() {
|
|||||||
config.logDir = `${config.dataDir}/log`;
|
config.logDir = `${config.dataDir}/log`;
|
||||||
config.publicDir = `${config.dataDir}/public`;
|
config.publicDir = `${config.dataDir}/public`;
|
||||||
config.publicFilesDir = `${config.dataDir}/public-files`;
|
config.publicFilesDir = `${config.dataDir}/public-files`;
|
||||||
config.filesPathStatic = `/book`;
|
config.rootPathStatic = `/root`;
|
||||||
config.filesDir = `${config.publicFilesDir}${config.filesPathStatic}`;
|
config.bookPathStatic = `${config.rootPathStatic}/book`;
|
||||||
|
config.bookDir = `${config.publicFilesDir}/book`;
|
||||||
|
|
||||||
configManager.config = config;
|
configManager.config = config;
|
||||||
|
|
||||||
await fs.ensureDir(config.dataDir);
|
await fs.ensureDir(config.dataDir);
|
||||||
await fs.ensureDir(config.filesDir);
|
await fs.ensureDir(config.bookDir);
|
||||||
await fs.ensureDir(config.tempDir);
|
await fs.ensureDir(config.tempDir);
|
||||||
await fs.emptyDir(config.tempDir);
|
await fs.emptyDir(config.tempDir);
|
||||||
|
|
||||||
@@ -148,7 +149,7 @@ async function main() {
|
|||||||
if (branch == 'development') {
|
if (branch == 'development') {
|
||||||
const devFileName = './dev.js'; //require ignored by pkg -50Mb executable size
|
const devFileName = './dev.js'; //require ignored by pkg -50Mb executable size
|
||||||
devModule = require(devFileName);
|
devModule = require(devFileName);
|
||||||
devModule.webpackDevMiddleware(app);
|
//devModule.webpackDevMiddleware(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (devModule)
|
if (devModule)
|
||||||
@@ -156,6 +157,8 @@ async function main() {
|
|||||||
|
|
||||||
const opds = require('./core/opds');
|
const opds = require('./core/opds');
|
||||||
opds(app, config);
|
opds(app, config);
|
||||||
|
|
||||||
|
const initStatic = require('./static');
|
||||||
initStatic(app, config);
|
initStatic(app, config);
|
||||||
|
|
||||||
const webAccess = new (require('./core/WebAccess'))(config);
|
const webAccess = new (require('./core/WebAccess'))(config);
|
||||||
@@ -179,73 +182,6 @@ async function main() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initStatic(app, config) {
|
|
||||||
/*
|
|
||||||
publicFilesDir = `${config.dataDir}/public-files`;
|
|
||||||
filesPathStatic = `/book`;
|
|
||||||
filesDir = `${config.publicFilesDir}${config.filesPathStatic}`;
|
|
||||||
*/
|
|
||||||
//загрузка или восстановление файлов в /files, при необходимости
|
|
||||||
app.use(config.filesPathStatic, async(req, res, next) => {
|
|
||||||
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path.extname(req.path) == '') {
|
|
||||||
const bookFile = `${config.filesDir}${req.path}`;
|
|
||||||
const bookFileDesc = `${bookFile}.d.json`;
|
|
||||||
|
|
||||||
let downFileName = '';
|
|
||||||
//восстановим из json-файла описания
|
|
||||||
try {
|
|
||||||
if (await fs.pathExists(bookFile) && await fs.pathExists(bookFileDesc)) {
|
|
||||||
await utils.touchFile(bookFile);
|
|
||||||
await utils.touchFile(bookFileDesc);
|
|
||||||
|
|
||||||
let desc = await fs.readFile(bookFileDesc, 'utf8');
|
|
||||||
desc = JSON.parse(desc);
|
|
||||||
downFileName = desc.downFileName;
|
|
||||||
} else {
|
|
||||||
await fs.remove(bookFile);
|
|
||||||
await fs.remove(bookFileDesc);
|
|
||||||
}
|
|
||||||
} catch(e) {
|
|
||||||
log(LM_ERR, e.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (downFileName) {
|
|
||||||
res.downFileName = downFileName;
|
|
||||||
|
|
||||||
if (!req.acceptsEncodings('gzip')) {
|
|
||||||
//не принимает gzip, тогда распакуем
|
|
||||||
const rawFile = `${bookFile}.raw`;
|
|
||||||
if (!await fs.pathExists(rawFile))
|
|
||||||
await utils.gunzipFile(bookFile, rawFile);
|
|
||||||
|
|
||||||
req.url += '.raw';
|
|
||||||
res.rawFile = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return next();
|
|
||||||
});
|
|
||||||
|
|
||||||
//заголовки при отдаче
|
|
||||||
app.use(config.filesPathStatic, express.static(config.filesDir, {
|
|
||||||
setHeaders: (res) => {
|
|
||||||
if (res.downFileName) {
|
|
||||||
if (!res.rawFile)
|
|
||||||
res.set('Content-Encoding', 'gzip');
|
|
||||||
|
|
||||||
res.set('Content-Disposition', `inline; filename*=UTF-8''${encodeURIComponent(res.downFileName)}`);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
app.use(express.static(config.publicDir));
|
|
||||||
}
|
|
||||||
|
|
||||||
(async() => {
|
(async() => {
|
||||||
try {
|
try {
|
||||||
await init();
|
await init();
|
||||||
|
|||||||
100
server/static.js
Normal file
100
server/static.js
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
const fs = require('fs-extra');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const express = require('express');
|
||||||
|
const utils = require('./core/utils');
|
||||||
|
const webAppDir = require('../build/appdir');
|
||||||
|
|
||||||
|
const log = new (require('./core/AppLogger'))().log;//singleton
|
||||||
|
|
||||||
|
module.exports = (app, config) => {
|
||||||
|
/*
|
||||||
|
config.bookPathStatic = `${config.rootPathStatic}/book`;
|
||||||
|
config.bookDir = `${config.publicFilesDir}/book`;
|
||||||
|
*/
|
||||||
|
//загрузка или восстановление файлов в /public-files, при необходимости
|
||||||
|
app.use(config.bookPathStatic, async(req, res, next) => {
|
||||||
|
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.extname(req.path) == '') {
|
||||||
|
const bookFile = `${config.bookDir}${req.path}`;
|
||||||
|
const bookFileDesc = `${bookFile}.d.json`;
|
||||||
|
|
||||||
|
let downFileName = '';
|
||||||
|
//восстановим из json-файла описания
|
||||||
|
try {
|
||||||
|
if (await fs.pathExists(bookFile) && await fs.pathExists(bookFileDesc)) {
|
||||||
|
await utils.touchFile(bookFile);
|
||||||
|
await utils.touchFile(bookFileDesc);
|
||||||
|
|
||||||
|
let desc = await fs.readFile(bookFileDesc, 'utf8');
|
||||||
|
desc = JSON.parse(desc);
|
||||||
|
downFileName = desc.downFileName;
|
||||||
|
} else {
|
||||||
|
await fs.remove(bookFile);
|
||||||
|
await fs.remove(bookFileDesc);
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
log(LM_ERR, e.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (downFileName) {
|
||||||
|
res.downFileName = downFileName;
|
||||||
|
|
||||||
|
if (!req.acceptsEncodings('gzip')) {
|
||||||
|
//не принимает gzip, тогда распакуем
|
||||||
|
const rawFile = `${bookFile}.raw`;
|
||||||
|
if (!await fs.pathExists(rawFile))
|
||||||
|
await utils.gunzipFile(bookFile, rawFile);
|
||||||
|
|
||||||
|
req.url += '.raw';
|
||||||
|
res.rawFile = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return next();
|
||||||
|
});
|
||||||
|
|
||||||
|
//заголовки при отдаче
|
||||||
|
app.use(config.bookPathStatic, express.static(config.bookDir, {
|
||||||
|
setHeaders: (res) => {
|
||||||
|
if (res.downFileName) {
|
||||||
|
if (!res.rawFile)
|
||||||
|
res.set('Content-Encoding', 'gzip');
|
||||||
|
|
||||||
|
res.set('Content-Disposition', `inline; filename*=UTF-8''${encodeURIComponent(res.downFileName)}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (config.rootPathStatic) {
|
||||||
|
//подмена rootPath в файлах статики WebApp при необходимости
|
||||||
|
app.use(config.rootPathStatic, async(req, res, next) => {
|
||||||
|
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
const reqPath = (req.path == '/' ? '/index.html' : req.path);
|
||||||
|
const ext = path.extname(reqPath);
|
||||||
|
if (ext == '.html' || ext == '.js' || ext == '.css') {
|
||||||
|
const reqFile = `${config.publicDir}${reqPath}`;
|
||||||
|
const flagFile = `${reqFile}.replaced`;
|
||||||
|
|
||||||
|
if (!await fs.pathExists(flagFile) && await fs.pathExists(reqFile)) {
|
||||||
|
const content = await fs.readFile(reqFile, 'utf8');
|
||||||
|
const re = new RegExp(`/${webAppDir}`, 'g');
|
||||||
|
await fs.writeFile(reqFile, content.replace(re, `${config.rootPathStatic}/${webAppDir}`));
|
||||||
|
await fs.writeFile(flagFile, '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//статика файлов WebApp
|
||||||
|
app.use(config.rootPathStatic, express.static(config.publicDir));
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user