[Kimchi-devel] [PATCH] Configure nginx to proxy connections to the websocket server.
Aline Manera
alinefm at linux.vnet.ibm.com
Wed Oct 14 21:57:48 UTC 2015
Hi Rob,
There are some tests failing with your patch. Please, run "make check"
on Wok directory to run the test cases.
On my system I got the following output. Could you, please, send the
problems and resend the patch?
Regards,
Aline Manera
-----------------------
EEEE...EE........
======================================================================
ERROR: test_development_env (test_exception.ExceptionTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_exception.py", line 96, in test_development_env
setup_server()
File "test_exception.py", line 43, in setup_server
environment=environment)
File "utils.py", line 122, in run_server
s = wok.server.Server(args)
File "/home/alinefm/kimchi/src/wok/server.py", line 62, in __init__
start_proxy(options)
File "/home/alinefm/kimchi/src/wok/proxy.py", line 98, in start_proxy
_create_proxy_config(options)
File "/home/alinefm/kimchi/src/wok/proxy.py", line 85, in
_create_proxy_config
display_proxy_port=options.display_proxy_port,
AttributeError: '_' object has no attribute 'display_proxy_port'
======================================================================
ERROR: test_development_env (test_exception.ExceptionTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_exception.py", line 48, in tearDown
test_server.stop()
AttributeError: 'NoneType' object has no attribute 'stop'
======================================================================
ERROR: test_production_env (test_exception.ExceptionTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_exception.py", line 54, in test_production_env
setup_server('production')
File "test_exception.py", line 43, in setup_server
environment=environment)
File "utils.py", line 122, in run_server
s = wok.server.Server(args)
File "/home/alinefm/kimchi/src/wok/server.py", line 62, in __init__
start_proxy(options)
File "/home/alinefm/kimchi/src/wok/proxy.py", line 98, in start_proxy
_create_proxy_config(options)
File "/home/alinefm/kimchi/src/wok/proxy.py", line 85, in
_create_proxy_config
display_proxy_port=options.display_proxy_port,
AttributeError: '_' object has no attribute 'display_proxy_port'
======================================================================
ERROR: test_production_env (test_exception.ExceptionTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_exception.py", line 48, in tearDown
test_server.stop()
AttributeError: 'NoneType' object has no attribute 'stop'
======================================================================
ERROR: setUpModule (test_plugin)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_plugin.py", line 45, in setUpModule
test_server = utils.run_server(host, port, ssl_port, test_mode=True)
File "utils.py", line 122, in run_server
s = wok.server.Server(args)
File "/home/alinefm/kimchi/src/wok/server.py", line 62, in __init__
start_proxy(options)
File "/home/alinefm/kimchi/src/wok/proxy.py", line 98, in start_proxy
_create_proxy_config(options)
File "/home/alinefm/kimchi/src/wok/proxy.py", line 85, in
_create_proxy_config
display_proxy_port=options.display_proxy_port,
AttributeError: '_' object has no attribute 'display_proxy_port'
======================================================================
ERROR: setUpModule (test_server)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_server.py", line 54, in setUpModule
cherrypy_port=cherrypy_port)
File "utils.py", line 122, in run_server
s = wok.server.Server(args)
File "/home/alinefm/kimchi/src/wok/server.py", line 62, in __init__
start_proxy(options)
File "/home/alinefm/kimchi/src/wok/proxy.py", line 98, in start_proxy
_create_proxy_config(options)
File "/home/alinefm/kimchi/src/wok/proxy.py", line 85, in
_create_proxy_config
display_proxy_port=options.display_proxy_port,
AttributeError: '_' object has no attribute 'display_proxy_port'
----------------------------------------------------------------------
Ran 13 tests in 7.959s
FAILED (errors=6)
Makefile:485: recipe for target 'check-local' failed
make[3]: *** [check-local] Error 1
make[3]: Leaving directory '/home/alinefm/kimchi/tests'
Makefile:359: recipe for target 'check-am' failed
make[2]: *** [check-am] Error 2
make[2]: Leaving directory '/home/alinefm/kimchi/tests'
Makefile:361: recipe for target 'check' failed
make[1]: *** [check] Error 2
make[1]: Leaving directory '/home/alinefm/kimchi/tests'
Makefile:498: recipe for target 'check-recursive' failed
make: *** [check-recursive] Error 1
On 09/10/2015 11:02, Rob Lemley wrote:
> This helps in networks with restrictive firewalls.
> - modify the nginx config file (kimchi.conf.in) and code to support changes
> - update README files
> - update firewalld config
> - move console.html into Kimchi plugin (websockify startup code is in Kimchi)
> - browsers tested - Firefox and Chrome (current versions)
> - tested on Centos 7
>
> Signed-off-by: Rob Lemley <rob.lemley at rochester.edu>
> ---
> configure.ac | 1 -
> docs/README.md | 5 +----
> src/firewalld.xml | 1 -
> src/nginx/wok.conf.in | 15 +++++++++++++
> src/wok/plugins/kimchi/config.py.in | 6 +++++-
> src/wok/plugins/kimchi/configure.ac | 1 +
> src/wok/plugins/kimchi/docs/README.md | 5 +----
> src/wok/plugins/kimchi/model/config.py | 2 ++
> src/wok/plugins/kimchi/ui/Makefile.am | 2 +-
> src/wok/plugins/kimchi/ui/js/src/kimchi.api.js | 18 ++++++++--------
> .../kimchi/ui/spice-html5/pages/spice_auto.html | 2 +-
> src/wok/plugins/kimchi/ui/websockify/Makefile.am | 22 +++++++++++++++++++
> src/wok/plugins/kimchi/ui/websockify/console.html | 25 ++++++++++++++++++++++
> src/wok/plugins/kimchi/vnc.py | 4 ++--
> src/wok/proxy.py | 1 +
> src/wokd.in | 1 +
> ui/pages/Makefile.am | 2 --
> ui/pages/websockify/Makefile.am | 22 -------------------
> ui/pages/websockify/console.html | 25 ----------------------
> 19 files changed, 87 insertions(+), 73 deletions(-)
> create mode 100644 src/wok/plugins/kimchi/ui/websockify/Makefile.am
> create mode 100644 src/wok/plugins/kimchi/ui/websockify/console.html
> delete mode 100644 ui/pages/websockify/Makefile.am
> delete mode 100644 ui/pages/websockify/console.html
>
> diff --git a/configure.ac b/configure.ac
> index 67c3920..d79de7a 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -123,7 +123,6 @@ AC_CONFIG_FILES([
> ui/libs/jquery-ui/themes/base/Makefile
> ui/libs/jquery-ui/themes/base/images/Makefile
> ui/pages/Makefile
> - ui/pages/websockify/Makefile
> contrib/Makefile
> contrib/DEBIAN/Makefile
> contrib/DEBIAN/control
> diff --git a/docs/README.md b/docs/README.md
> index f0b8697..2686eff 100644
> --- a/docs/README.md
> +++ b/docs/README.md
> @@ -119,26 +119,23 @@ Run
> If you cannot access Wok, take a look at these 2 points:
>
> 1. Firewall:
> -Wok uses by default the ports 8000, 8001 and 64667. To allow incoming connections:
> +Wok uses by default the ports 8000 and 8001. To allow incoming connections:
>
> For system using firewalld, do:
>
> $ sudo firewall-cmd --add-port=8000/tcp --permanent
> $ sudo firewall-cmd --add-port=8001/tcp --permanent
> - $ sudo firewall-cmd --add-port=64667/tcp --permanent
> $ sudo firewall-cmd --reload
>
> For openSUSE systems, do:
>
> $ sudo /sbin/SuSEfirewall2 open EXT TCP 8000
> $ sudo /sbin/SuSEfirewall2 open EXT TCP 8001
> - $ sudo /sbin/SuSEfirewall2 open EXT TCP 64667
>
> For system using iptables, do:
>
> $ sudo iptables -A INPUT -p tcp --dport 8000 -j ACCEPT
> $ sudo iptables -A INPUT -p tcp --dport 8001 -j ACCEPT
> - $ sudo iptables -A INPUT -p tcp --dport 64667 -j ACCEPT
>
> Don't forget to correctly save the rules.
>
> diff --git a/src/firewalld.xml b/src/firewalld.xml
> index ff9fafe..3a564fe 100644
> --- a/src/firewalld.xml
> +++ b/src/firewalld.xml
> @@ -4,5 +4,4 @@
> <description>wokd is a daemon service for wok which is a web framework.</description>
> <port protocol="tcp" port="8000"/>
> <port protocol="tcp" port="8001"/>
> - <port protocol="tcp" port="64667"/>
> </service>
> diff --git a/src/nginx/wok.conf.in b/src/nginx/wok.conf.in
> index db68893..16b0201 100644
> --- a/src/nginx/wok.conf.in
> +++ b/src/nginx/wok.conf.in
> @@ -49,6 +49,15 @@ http {
> proxy_read_timeout 600;
> send_timeout 600;
>
> + map $http_upgrade $connection_upgrade {
> + default upgrade;
> + '' close;
> + }
> +
> + upstream websocket {
> + server 127.0.0.1:${display_proxy_port};
> + }
> +
> server {
> listen ${proxy_ssl_port} ssl;
>
> @@ -71,6 +80,12 @@ http {
> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
> proxy_redirect http://127.0.0.1:${wokd_port}/ https://$host:${proxy_ssl_port}/;
> }
> + location /websockify {
> + proxy_pass http://websocket;
> + proxy_http_version 1.1;
> + proxy_set_header Upgrade $http_upgrade;
> + proxy_set_header Connection $connection_upgrade;
> + }
> }
>
> server {
> diff --git a/src/wok/plugins/kimchi/config.py.in b/src/wok/plugins/kimchi/config.py.in
> index 6ae0ccd..425eaed 100644
> --- a/src/wok/plugins/kimchi/config.py.in
> +++ b/src/wok/plugins/kimchi/config.py.in
> @@ -81,6 +81,8 @@ class KimchiPaths(PluginPaths):
> super(KimchiPaths, self).__init__('kimchi')
> self.spice_file = os.path.join(self.ui_dir,
> 'spice-html5/pages/spice_auto.html')
> + self.console_file = os.path.join(self.ui_dir,
> + 'websockify/console.html')
>
> if __with_spice__ == 'yes':
> self.spice_dir = self.add_prefix('ui/spice-html5')
> @@ -115,7 +117,9 @@ class KimchiConfig(PluginConfig):
> '/spice_auto.html': {'type': 'file',
> 'path': kimchiPaths.spice_file},
> '/spice-html5/spice.css': {'type': 'file',
> - 'path': kimchiPaths.spice_css_file}}
> + 'path': kimchiPaths.spice_css_file},
> + '/websockify/console.html': {'type': 'file',
> + 'path': kimchiPaths.console_file}}
>
> custom_config = {}
> for uri, data in static_config.iteritems():
> diff --git a/src/wok/plugins/kimchi/configure.ac b/src/wok/plugins/kimchi/configure.ac
> index adab45b..3eeb4b3 100644
> --- a/src/wok/plugins/kimchi/configure.ac
> +++ b/src/wok/plugins/kimchi/configure.ac
> @@ -105,6 +105,7 @@ AC_CONFIG_FILES([
> ui/pages/help/ru_RU/Makefile
> ui/pages/help/zh_CN/Makefile
> ui/pages/help/zh_TW/Makefile
> + ui/websockify/Makefile
> contrib/Makefile
> contrib/DEBIAN/Makefile
> contrib/DEBIAN/control
> diff --git a/src/wok/plugins/kimchi/docs/README.md b/src/wok/plugins/kimchi/docs/README.md
> index fb0aef9..3c30d8e 100644
> --- a/src/wok/plugins/kimchi/docs/README.md
> +++ b/src/wok/plugins/kimchi/docs/README.md
> @@ -135,23 +135,20 @@ Run
> If you cannot access Wok, take a look at these 2 points:
>
> 1. Firewall
> -Wok uses by default the ports 8000, 8001 and 64667. To allow incoming connections:
> +Wok uses by default the ports 8000 and 8001. To allow incoming connections:
>
> For system using firewalld, do:
> sudo firewall-cmd --add-port=8000/tcp --permanent
> sudo firewall-cmd --add-port=8001/tcp --permanent
> - sudo firewall-cmd --add-port=64667/tcp --permanent
> sudo firewall-cmd --reload
>
> For openSUSE systems, do:
> sudo /sbin/SuSEfirewall2 open EXT TCP 8000
> sudo /sbin/SuSEfirewall2 open EXT TCP 8001
> - sudo /sbin/SuSEfirewall2 open EXT TCP 64667
>
> For system using iptables, do:
> sudo iptables -A INPUT -p tcp --dport 8000 -j ACCEPT
> sudo iptables -A INPUT -p tcp --dport 8001 -j ACCEPT
> - sudo iptables -A INPUT -p tcp --dport 64667 -j ACCEPT
>
> Don't forget to correctly save the rules.
>
> diff --git a/src/wok/plugins/kimchi/model/config.py b/src/wok/plugins/kimchi/model/config.py
> index b6cc4d9..cc7fe4d 100644
> --- a/src/wok/plugins/kimchi/model/config.py
> +++ b/src/wok/plugins/kimchi/model/config.py
> @@ -42,7 +42,9 @@ class ConfigModel(object):
>
> def lookup(self, name):
> proxy_port = kconfig.get('display', 'display_proxy_port')
> + ssl_port = kconfig.get('server', 'ssl_port')
> return {'display_proxy_port': proxy_port,
> + 'ssl_port': ssl_port,
> 'version': get_version()}
>
>
> diff --git a/src/wok/plugins/kimchi/ui/Makefile.am b/src/wok/plugins/kimchi/ui/Makefile.am
> index 21fe703..62bcfeb 100644
> --- a/src/wok/plugins/kimchi/ui/Makefile.am
> +++ b/src/wok/plugins/kimchi/ui/Makefile.am
> @@ -15,6 +15,6 @@
> # See the License for the specific language governing permissions and
> # limitations under the License.
>
> -SUBDIRS = config css images js pages spice-html5
> +SUBDIRS = config css images js pages spice-html5 websockify
>
> uidir = $(datadir)/wok/plugins/kimchi/ui
> diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js
> index c82d040..0e784f5 100644
> --- a/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js
> +++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js
> @@ -343,16 +343,16 @@ var kimchi = {
> type : 'GET',
> dataType : 'json'
> }).done(function(data, textStatus, xhr) {
> - proxy_port = data['display_proxy_port'];
> + ssl_port = data['ssl_port'];
> wok.requestJSON({
> url : "plugins/kimchi/vms/" + encodeURIComponent(vm) + "/connect",
> type : "POST",
> dataType : "json"
> }).done(function() {
> - url = 'https://' + location.hostname + ':' + proxy_port;
> - url += "/console.html?url=";
> + url = 'https://' + location.hostname + ':' + ssl_port;
> + url += "/plugins/kimchi/websockify/console.html?url=";
> url += encodeURIComponent("plugins/kimchi/novnc/vnc_auto.html");
> - url += "&port=" + proxy_port;
> + url += "&port=" + ssl_port;
> /*
> * From python documentation base64.urlsafe_b64encode(s)
> * substitutes - instead of + and _ instead of / in the
> @@ -360,7 +360,7 @@ var kimchi = {
> * contain = which is not safe in a URL query component.
> * So remove it when needed as base64 can work well without it.
> * */
> - url += "&path=?token=" + wok.urlSafeB64Encode(vm).replace(/=*$/g, "");
> + url += "&path=websockify?token=" + wok.urlSafeB64Encode(vm).replace(/=*$/g, "");
> url += "&wok=" + location.port;
> url += '&encrypt=1';
> window.open(url);
> @@ -376,15 +376,15 @@ var kimchi = {
> type : 'GET',
> dataType : 'json'
> }).done(function(data, textStatus, xhr) {
> - proxy_port = data['display_proxy_port'];
> + ssl_port = data['ssl_port'];
> wok.requestJSON({
> url : "plugins/kimchi/vms/" + encodeURIComponent(vm) + "/connect",
> type : "POST",
> dataType : "json"
> }).done(function(data, textStatus, xhr) {
> - url = 'https://' + location.hostname + ':' + proxy_port;
> - url += "/console.html?url=plugins/kimchi/spice_auto.html";
> - url += "&port=" + proxy_port + "&listen=" + location.hostname;
> + url = 'https://' + location.hostname + ':' + ssl_port;
> + url += "/plugins/kimchi/websockify/console.html?url=plugins/kimchi/spice_auto.html";
> + url += "&port=" + ssl_port + "&listen=" + location.hostname;
> /*
> * From python documentation base64.urlsafe_b64encode(s)
> * substitutes - instead of + and _ instead of / in the
> diff --git a/src/wok/plugins/kimchi/ui/spice-html5/pages/spice_auto.html b/src/wok/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
> index c87f5c2..91ddadb 100644
> --- a/src/wok/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
> +++ b/src/wok/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
> @@ -143,7 +143,7 @@
> * to point wok.user to a specific console represented by
> * token value.
> */
> - uri = scheme + host + ":" + port + "/?token=" + token;
> + uri = scheme + host + ":" + port + "/websockify?token=" + token;
>
> try
> {
> diff --git a/src/wok/plugins/kimchi/ui/websockify/Makefile.am b/src/wok/plugins/kimchi/ui/websockify/Makefile.am
> new file mode 100644
> index 0000000..ca3ddc3
> --- /dev/null
> +++ b/src/wok/plugins/kimchi/ui/websockify/Makefile.am
> @@ -0,0 +1,22 @@
> +#
> +# Project Wok
> +#
> +# Copyright IBM, Corp. 2014-2015
> +#
> +# Code derived from Project Kimchi
> +#
> +# Licensed under the Apache License, Version 2.0 (the "License");
> +# you may not use this file except in compliance with the License.
> +# You may obtain a copy of the License at
> +#
> +# http://www.apache.org/licenses/LICENSE-2.0
> +#
> +# Unless required by applicable law or agreed to in writing, software
> +# distributed under the License is distributed on an "AS IS" BASIS,
> +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> +# See the License for the specific language governing permissions and
> +# limitations under the License.
> +
> +websockifyhtmldir = $(datadir)/wok/ui/pages/websockify
> +
> +dist_websockifyhtml_DATA = $(wildcard *.html) $(NULL)
> diff --git a/src/wok/plugins/kimchi/ui/websockify/console.html b/src/wok/plugins/kimchi/ui/websockify/console.html
> new file mode 100644
> index 0000000..e0a3cd4
> --- /dev/null
> +++ b/src/wok/plugins/kimchi/ui/websockify/console.html
> @@ -0,0 +1,25 @@
> +<!DOCTYPE html>
> +<html>
> + <head>
> + <script type="text/javascript">
> + redirectToWok = function() {
> + var query = window.location.search;
> +
> + var path = /.*url=(.*?)(&|$)/g.exec(query)[1];
> + query = query.replace("url=" + path + "&", "")
> + query = query.replace("url=" + path, "")
> +
> + var wok_port = /.*wok=(.*?)(&|$)/g.exec(query)[1];
> + query = query.replace("wok=" + wok_port + "&", "")
> + query = query.replace("wok=" + wok_port, "")
> +
> + var url = "https://" + location.hostname + ":" + wok_port + "/";
> + url += decodeURIComponent(path) + query
> +
> + window.location.replace(url)
> + }
> + </script>
> + </head>
> +
> + <body onload="redirectToWok()"/>
> +</html>
> diff --git a/src/wok/plugins/kimchi/vnc.py b/src/wok/plugins/kimchi/vnc.py
> index 2532449..5d10bc6 100644
> --- a/src/wok/plugins/kimchi/vnc.py
> +++ b/src/wok/plugins/kimchi/vnc.py
> @@ -43,10 +43,10 @@ def new_ws_proxy():
> cert = '%s/wok-cert.pem' % paths.conf_dir
> key = '%s/wok-key.pem' % paths.conf_dir
>
> - params = {'web': os.path.join(paths.ui_dir, 'pages/websockify'),
> + params = {'listen_host': '127.0.0.1',
> 'listen_port': config.get('display', 'display_proxy_port'),
> 'target_cfg': WS_TOKENS_DIR,
> - 'key': key, 'cert': cert, 'ssl_only': True}
> + 'ssl_only': False}
>
> def start_proxy():
> server = WebSocketProxy(**params)
> diff --git a/src/wok/proxy.py b/src/wok/proxy.py
> index 46ce857..f9f1607 100644
> --- a/src/wok/proxy.py
> +++ b/src/wok/proxy.py
> @@ -82,6 +82,7 @@ def _create_proxy_config(options):
> proxy_port=options.port,
> wokd_port=options.cherrypy_port,
> proxy_ssl_port=options.ssl_port,
> + display_proxy_port=options.display_proxy_port,
> cert_pem=cert, cert_key=key,
> max_body_size=eval(options.max_body_size),
> dhparams_pem=dhparams_pem)
> diff --git a/src/wokd.in b/src/wokd.in
> index c5510fd..a23fcfc 100644
> --- a/src/wokd.in
> +++ b/src/wokd.in
> @@ -94,6 +94,7 @@ def main(options):
> setattr(options, 'ssl_key', config.config.get('server', 'ssl_key'))
> setattr(options, 'max_body_size',
> config.config.get('server', 'max_body_size'))
> + setattr(options, 'display_proxy_port', config.config.get('display', 'display_proxy_port'))
>
> wok.server.main(options)
>
> diff --git a/ui/pages/Makefile.am b/ui/pages/Makefile.am
> index 2488203..85faa80 100644
> --- a/ui/pages/Makefile.am
> +++ b/ui/pages/Makefile.am
> @@ -17,8 +17,6 @@
> # See the License for the specific language governing permissions and
> # limitations under the License.
>
> -SUBDIRS = websockify
> -
> htmldir = $(datadir)/wok/ui/pages
>
> dist_html_DATA = $(wildcard *.tmpl) $(NULL)
> diff --git a/ui/pages/websockify/Makefile.am b/ui/pages/websockify/Makefile.am
> deleted file mode 100644
> index ca3ddc3..0000000
> --- a/ui/pages/websockify/Makefile.am
> +++ /dev/null
> @@ -1,22 +0,0 @@
> -#
> -# Project Wok
> -#
> -# Copyright IBM, Corp. 2014-2015
> -#
> -# Code derived from Project Kimchi
> -#
> -# Licensed under the Apache License, Version 2.0 (the "License");
> -# you may not use this file except in compliance with the License.
> -# You may obtain a copy of the License at
> -#
> -# http://www.apache.org/licenses/LICENSE-2.0
> -#
> -# Unless required by applicable law or agreed to in writing, software
> -# distributed under the License is distributed on an "AS IS" BASIS,
> -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> -# See the License for the specific language governing permissions and
> -# limitations under the License.
> -
> -websockifyhtmldir = $(datadir)/wok/ui/pages/websockify
> -
> -dist_websockifyhtml_DATA = $(wildcard *.html) $(NULL)
> diff --git a/ui/pages/websockify/console.html b/ui/pages/websockify/console.html
> deleted file mode 100644
> index e0a3cd4..0000000
> --- a/ui/pages/websockify/console.html
> +++ /dev/null
> @@ -1,25 +0,0 @@
> -<!DOCTYPE html>
> -<html>
> - <head>
> - <script type="text/javascript">
> - redirectToWok = function() {
> - var query = window.location.search;
> -
> - var path = /.*url=(.*?)(&|$)/g.exec(query)[1];
> - query = query.replace("url=" + path + "&", "")
> - query = query.replace("url=" + path, "")
> -
> - var wok_port = /.*wok=(.*?)(&|$)/g.exec(query)[1];
> - query = query.replace("wok=" + wok_port + "&", "")
> - query = query.replace("wok=" + wok_port, "")
> -
> - var url = "https://" + location.hostname + ":" + wok_port + "/";
> - url += decodeURIComponent(path) + query
> -
> - window.location.replace(url)
> - }
> - </script>
> - </head>
> -
> - <body onload="redirectToWok()"/>
> -</html>
More information about the Kimchi-devel
mailing list