diff --git a/bin/migrate_create b/bin/migrate_create new file mode 100755 index 000000000..dc2b5edf6 --- /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 000000000..63698fa1c --- /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 bde76cd70..11155f094 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 17fc87c71..da4dfdc31 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 0d0f45d24..5a85cd8ff 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 a4ad212c5..5b682169d 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 f4100551b..8c69fa0c8 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 82ea623f5..bf75f36f5 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 }; } });