From 83686c45351c469cdd6598c4882f3c240653fb1e Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Sat, 29 Sep 2018 16:02:05 +1000 Subject: [PATCH] Added websock upgrade option for base proxy host locations --- bin/migrate_create | 26 +++++++++++++ .../migrations/20180929054513_websockets.js | 37 +++++++++++++++++++ src/backend/schema/endpoints/proxy-hosts.json | 14 +++++++ src/backend/templates/proxy_host.conf | 6 +++ src/frontend/js/app/nginx/proxy/form.ejs | 9 +++++ src/frontend/js/app/nginx/proxy/form.js | 7 ++-- src/frontend/js/i18n/messages.json | 3 +- src/frontend/js/models/proxy-host.js | 33 +++++++++-------- 8 files changed, 115 insertions(+), 20 deletions(-) create mode 100755 bin/migrate_create create mode 100644 src/backend/migrations/20180929054513_websockets.js diff --git a/bin/migrate_create b/bin/migrate_create new file mode 100755 index 0000000..dc2b5ed --- /dev/null +++ b/bin/migrate_create @@ -0,0 +1,26 @@ +#!/bin/bash + +if [ "$1" == "" ]; then + echo "Error: migrate name must be specified as first arg" + exit 1 +else + # Code path + SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + if hash realpath 2>/dev/null; then + export CODEBASE=$(realpath $SCRIPT_DIR/..) + elif hash grealpath 2>/dev/null; then + export CODEBASE=$(grealpath $SCRIPT_DIR/..) + else + export CODEBASE=$(readlink -e $SCRIPT_DIR/..) + fi + + if [ -z "$CODEBASE" ]; then + echo "Unable to determine absolute codebase directory" + exit 1 + fi + + cd "$CODEBASE" + + sudo /usr/local/bin/docker-compose run --rm --no-deps app node node_modules/knex/bin/cli.js migrate:make "$1" + exit $? +fi diff --git a/src/backend/migrations/20180929054513_websockets.js b/src/backend/migrations/20180929054513_websockets.js new file mode 100644 index 0000000..63698fa --- /dev/null +++ b/src/backend/migrations/20180929054513_websockets.js @@ -0,0 +1,37 @@ +'use strict'; + +const migrate_name = 'websockets'; +const logger = require('../logger').migrate; + +/** + * Migrate + * + * @see http://knexjs.org/#Schema + * + * @param {Object} knex + * @param {Promise} Promise + * @returns {Promise} + */ +exports.up = function (knex/*, Promise*/) { + logger.info('[' + migrate_name + '] Migrating Up...'); + + return knex.schema.table('proxy_host', function (proxy_host) { + proxy_host.integer('allow_websocket_upgrade').notNull().unsigned().defaultTo(0); + }) + .then(() => { + logger.info('[' + migrate_name + '] proxy_host Table altered'); + }); + +}; + +/** + * Undo Migrate + * + * @param {Object} knex + * @param {Promise} Promise + * @returns {Promise} + */ +exports.down = function (knex, Promise) { + logger.warn('[' + migrate_name + '] You can\'t migrate down this one.'); + return Promise.resolve(true); +}; \ No newline at end of file diff --git a/src/backend/schema/endpoints/proxy-hosts.json b/src/backend/schema/endpoints/proxy-hosts.json index bde76cd..11155f0 100644 --- a/src/backend/schema/endpoints/proxy-hosts.json +++ b/src/backend/schema/endpoints/proxy-hosts.json @@ -39,6 +39,11 @@ "caching_enabled": { "$ref": "../definitions.json#/definitions/caching_enabled" }, + "allow_websocket_upgrade": { + "description": "Allow Websocket Upgrade for all paths", + "example": true, + "type": "boolean" + }, "access_list_id": { "$ref": "../definitions.json#/definitions/access_list_id" }, @@ -80,6 +85,9 @@ "caching_enabled": { "$ref": "#/definitions/caching_enabled" }, + "allow_websocket_upgrade": { + "$ref": "#/definitions/allow_websocket_upgrade" + }, "access_list_id": { "$ref": "#/definitions/access_list_id" }, @@ -148,6 +156,9 @@ "caching_enabled": { "$ref": "#/definitions/caching_enabled" }, + "allow_websocket_upgrade": { + "$ref": "#/definitions/allow_websocket_upgrade" + }, "access_list_id": { "$ref": "#/definitions/access_list_id" }, @@ -200,6 +211,9 @@ "caching_enabled": { "$ref": "#/definitions/caching_enabled" }, + "allow_websocket_upgrade": { + "$ref": "#/definitions/allow_websocket_upgrade" + }, "access_list_id": { "$ref": "#/definitions/access_list_id" }, diff --git a/src/backend/templates/proxy_host.conf b/src/backend/templates/proxy_host.conf index 17fc87c..da4dfdc 100644 --- a/src/backend/templates/proxy_host.conf +++ b/src/backend/templates/proxy_host.conf @@ -22,6 +22,12 @@ server { {% include "_forced_ssl.conf" %} + {% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %} + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_http_version 1.1; + {% endif %} + # Proxy! include conf.d/include/proxy.conf; } diff --git a/src/frontend/js/app/nginx/proxy/form.ejs b/src/frontend/js/app/nginx/proxy/form.ejs index 0d0f45d..5a85cd8 100644 --- a/src/frontend/js/app/nginx/proxy/form.ejs +++ b/src/frontend/js/app/nginx/proxy/form.ejs @@ -50,6 +50,15 @@ +
+
+ +
+
diff --git a/src/frontend/js/app/nginx/proxy/form.js b/src/frontend/js/app/nginx/proxy/form.js index a4ad212..5b68216 100644 --- a/src/frontend/js/app/nginx/proxy/form.js +++ b/src/frontend/js/app/nginx/proxy/form.js @@ -54,9 +54,10 @@ module.exports = Mn.View.extend({ let data = this.ui.form.serializeJSON(); // Manipulate - data.forward_port = parseInt(data.forward_port, 10); - data.block_exploits = !!data.block_exploits; - data.caching_enabled = !!data.caching_enabled; + data.forward_port = parseInt(data.forward_port, 10); + data.block_exploits = !!data.block_exploits; + data.caching_enabled = !!data.caching_enabled; + data.allow_websocket_upgrade = !!data.allow_websocket_upgrade; if (typeof data.ssl_forced !== 'undefined' && data.ssl_forced === '1') { data.ssl_forced = true; diff --git a/src/frontend/js/i18n/messages.json b/src/frontend/js/i18n/messages.json index f410055..8c69fa0 100644 --- a/src/frontend/js/i18n/messages.json +++ b/src/frontend/js/i18n/messages.json @@ -98,7 +98,8 @@ "delete-confirm": "Are you sure you want to delete the Proxy host for: {domains}?", "help-title": "What is a Proxy Host?", "help-content": "A Proxy Host is the incoming endpoint for a web service that you want to forward.\nIt provides optional SSL termination for your service that might not have SSL support built in.\nProxy Hosts are the most common use for the Nginx Proxy Manager.", - "access-list": "Access List" + "access-list": "Access List", + "allow-websocket-upgrade": "Allow Websocket HTTP Upgrades" }, "redirection-hosts": { "title": "Redirection Hosts", diff --git a/src/frontend/js/models/proxy-host.js b/src/frontend/js/models/proxy-host.js index 82ea623..bf75f36 100644 --- a/src/frontend/js/models/proxy-host.js +++ b/src/frontend/js/models/proxy-host.js @@ -7,23 +7,24 @@ const model = Backbone.Model.extend({ defaults: function () { return { - id: undefined, - created_on: null, - modified_on: null, - domain_names: [], - forward_ip: '', - forward_port: null, - access_list_id: 0, - certificate_id: 0, - ssl_forced: false, - caching_enabled: false, - block_exploits: false, - advanced_config: '', - meta: {}, + id: undefined, + created_on: null, + modified_on: null, + domain_names: [], + forward_ip: '', + forward_port: null, + access_list_id: 0, + certificate_id: 0, + ssl_forced: false, + caching_enabled: false, + allow_websocket_upgrade: false, + block_exploits: false, + advanced_config: '', + meta: {}, // The following are expansions: - owner: null, - access_list: null, - certificate: null + owner: null, + access_list: null, + certificate: null }; } });