Skip to content

Commit

Permalink
add option to listen via unix socket
Browse files Browse the repository at this point in the history
add `X-Forwarded-For` in nginx note (fix error in app.js:86)
fix: eslint problem in app.js
fix: TannerReynolds#90
  • Loading branch information
Wireless4024 committed Nov 2, 2021
1 parent e708060 commit f739c9e
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 32 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ You must fill this out for the webserver to work properly. Below explains the co
"domain": "*.example.com", // Domain server will use. Will error if domain not used in request. Place "*" as the subdomain to enable wildcard subdomains for the webserver.
"puploadKeyGenLength": 64, // Amount of characters server should use for pupload files
"public": false, // Disables auth and does not render a password field for /upload
"socket": "", // socket path to listen eg. /tmp/shares.sock
"socketOnly": true, // do not listen via ip if socket is set (ignore options secure, port)
"maxUploadSize": 50, // max upload size for non-admins using regular key in MB
"markdown": true, // enables markdown rendering (upload whole .md file for render)
"port": 80, // port to listen on
Expand Down Expand Up @@ -86,6 +88,7 @@ If you're configuring this webserver to run through an Nginx reverse proxy, make
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache_bypass $http_upgrade;
```
This is generally some things you want to add to your config, and is what's actually required for ShareS to work properly. This is because ShareS returns uploads like `[http/https]://[requested url]/[filename]` and since you're running ShareS through a reverse proxy, unless you're passing along the *original* headers, ShareS is most likely just going to send you something like `http://[server's real ip address]/[filename]`
Expand Down
2 changes: 2 additions & 0 deletions src/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"domain": "example.com",
"puploadKeyGenLength": 64,
"public": false,
"socket": "",
"socketOnly": true,
"maxUploadSize": 50,
"markdown": true,
"port": 80,
Expand Down
79 changes: 47 additions & 32 deletions src/server/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class ShareXAPI {
this.c = c;
this.monitorChannel = null;
this.checkMonth();
this.c.discordToken && this.c.discordToken !== undefined && this.c.discrdToken !== null
this.c.discordToken && this.c.discordToken !== undefined && this.c.discordToken !== null
? this.runDiscordBot()
: this.log.verbose('No Discord Token provided...\nContinuing without Discord connection...');
this.app = app;
Expand All @@ -60,16 +60,16 @@ class ShareXAPI {

/* Don't allow access if not accessed with configured domain */
this.app.use((req, res, next) => {
if(this.c.domain === '*') {
if (this.c.domain === '*') {
next();
} else if(req.headers.host !== this.c.domain.toLowerCase() && !this.c.domain.includes('*')) {
} else if (req.headers.host !== this.c.domain.toLowerCase() && !this.c.domain.includes('*')) {
res.statusCode = 401;
res.write('Error 401: Unauthorized Domain');
return res.end();
} else if(this.c.domain.includes('*')) {
let reqParts = req.headers.host.toLowerCase().split('.');
let domainParts = this.c.domain.toLowerCase().split('.')
if(reqParts[1] === domainParts[1] && reqParts[2] === domainParts[2]) {
} else if (this.c.domain.includes('*')) {
const reqParts = req.headers.host.toLowerCase().split('.');
const domainParts = this.c.domain.toLowerCase().split('.');
if (reqParts[1] === domainParts[1] && reqParts[2] === domainParts[2]) {
next();
} else {
res.statusCode = 401;
Expand Down Expand Up @@ -114,7 +114,7 @@ class ShareXAPI {
this.app.use((req, res, next) => {
if (req.method === 'GET') {
const userIP = req.headers['x-forwarded-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
let file = req.path;
const file = req.path;
// Not ignoring these files causes bloat in the db
const ignored = ['/favicon.ico', '/assets/css/styles.min.css', '/highlight.pack.js', '/highlightjs-line-numbers.min.js', '/paste.css', '/atom-one-dark.css'];
let exists = this.db.get('files').find({ path: file }).value();
Expand Down Expand Up @@ -172,7 +172,7 @@ class ShareXAPI {
});
// All files in /uploads/ are publicly accessible via http
this.app.use(express.static(`${__dirname}/uploads/`, {
extensions: this.c.admin.allowed.includes("*") ? null : this.c.admin.allowed,
extensions: this.c.admin.allowed.includes('*') ? null : this.c.admin.allowed,
}));
this.app.use(express.static(`${__dirname}/views/`, {
extensions: ['css'],
Expand Down Expand Up @@ -234,32 +234,47 @@ class ShareXAPI {
* @returns {void}
*/
async startServer() {
if (this.c.secure) {
/** if the secure option is set to true in config,
* it will boot in https so long as it detects
* key.pem and cert.pem in the src directory
*/
if (fs.existsSync(`${__dirname}/../key.pem`) && fs.existsSync(`${__dirname}/../cert.pem`)) {
const privateKey = fs.readFileSync(`${__dirname}/../key.pem`);
const certificate = fs.readFileSync(`${__dirname}/../cert.pem`);
https.createServer({
key: privateKey,
cert: certificate,
}, this.app).listen(this.c.securePort, '0.0.0.0');
if (!this.c.socketOnly || !this.c.socket) {
if (this.c.secure) {
/** if the secure option is set to true in config,
* it will boot in https so long as it detects
* key.pem and cert.pem in the src directory
*/
if (fs.existsSync(`${__dirname}/../key.pem`) && fs.existsSync(`${__dirname}/../cert.pem`)) {
const privateKey = fs.readFileSync(`${__dirname}/../key.pem`);
const certificate = fs.readFileSync(`${__dirname}/../cert.pem`);
https.createServer({
key: privateKey,
cert: certificate,
}, this.app).listen(this.c.securePort, '0.0.0.0');
} else {
// CF Flexible SSL
/** if no key & cert pem files are detected,
* it will still run in secure mode (returning urls with https)
* so that it's compatible with CF flexible SSL
* and SSL configurations via a reverse proxy */
this.app.listen(this.c.securePort, '0.0.0.0', () => {
this.log.warning('Server using flexible SSL secure setting\nTo run a full SSL setting, ensure key.pem and cert.pem are in the /src folder');
});
}
this.log.success(`Secure server listening on port ${this.c.securePort}`);
} else {
// CF Flexible SSL
/** if no key & cert pem files are detected,
* it will still run in secure mode (returning urls with https)
* so that it's compatible with CF flexible SSL
* and SSL configurations via a reverse proxy */
this.app.listen(this.c.securePort, '0.0.0.0', () => {
this.log.warning('Server using flexible SSL secure setting\nTo run a full SSL setting, ensure key.pem and cert.pem are in the /src folder');
this.app.listen(this.c.port, '0.0.0.0', () => {
this.log.success(`Server listening on port ${this.c.port}`);
});
}
this.log.success(`Secure server listening on port ${this.c.securePort}`);
} else {
this.app.listen(this.c.port, '0.0.0.0', () => {
this.log.success(`Server listening on port ${this.c.port}`);
}
if (this.c.socket) {
const socket = this.c.socket.toString();
// https://stackoverflow.com/a/21385803
fs.stat(socket, (err) => {
if (!err) { fs.unlinkSync(socket); }
this.app.listen(/** @type string */socket, () => {
if (fs.chmodSync) {
fs.chmodSync(socket, '777');
}
this.log.success(`Server listening on socket ${socket}`);
});
});
}
}
Expand Down

0 comments on commit f739c9e

Please sign in to comment.