Commit 306e5b4f authored by Łukasz Nowak's avatar Łukasz Nowak

caddy-frontend: Implement type:websocket

By default whole slave makes websocket connection to the backend.
With websocket-path, only the path has websocket style connections,
the rest is standard HTTP.
parent 0a217aa2
......@@ -26,7 +26,7 @@ md5sum = bde0f62dfe2eeef8f10b4315535095cb
[template-apache-replicate]
filename = instance-apache-replicate.cfg.in
md5sum = a4303904fa1dfebcbb40f28cd715e7cf
md5sum = d62aefe002ec13875924e4c219914795
[template-slave-list]
filename = templates/apache-custom-slave-list.cfg.in
......@@ -54,7 +54,7 @@ md5sum = f20d6c3d2d94fb685f8d26dfca1e822b
[template-default-slave-virtualhost]
filename = templates/default-virtualhost.conf.in
md5sum = 9de6875635038f88be4f039e03deb1c0
md5sum = c2ac89bdb835855b7a70829705d41516
[template-cached-slave-virtualhost]
filename = templates/cached-virtualhost.conf.in
......
......@@ -82,7 +82,7 @@ context =
{% set slave_type = slave.get('type') %}
{% if slave_type == 'eventsource' %}
{% do slave_error_list.append('type:eventsource is not implemented') %}
{% elif slave_type not in [None, '', 'default', 'zope', 'redirect', 'notebook'] %}
{% elif slave_type not in [None, '', 'default', 'zope', 'redirect', 'notebook', 'websocket'] %}
{% do slave_error_list.append('type:%s is not supported' % (slave_type,)) %}
{% endif %}
{# BBB: apache_custom_https AND apache_custom_http #}
......
......@@ -107,6 +107,12 @@
"title": "type:zope Backend Path",
"type": "string"
},
"websocket-path": {
"default": "",
"description": "Path to the websocket application. If none set the whole slave will be websocket, if set then / will be HTTP, and /<websocket-path> will be WSS.",
"title": "type:websocket Websocket Application Path",
"type": "string"
},
"prefer-gzip-encoding-to-backend": {
"default": "false",
"description": "If set to true, frontend will rewrite Accept-Encoding request header to simply 'gzip' for all variants of Accept-Encoding containing 'gzip', in order to maximize cache hits for resources cached with Vary: Accept-Encoding when enable_cache is used",
......@@ -154,6 +160,7 @@
"zope",
"redirect",
"notebook",
"websocket",
"eventsource"
],
"title": "Backend Type",
......
......@@ -23,8 +23,9 @@
{%- do https_host_list.append('https://%s:%s' % (host, slave_parameter['https_port'] )) %}
{%- endfor %} {#- for host in host_list #}
{%- set default_path = slave_parameter.get('default-path', '').strip('/') | urlencode %}
{%- if slave_type == 'notebook' %}
{# notebook needs http 1.1 max #}
{%- set websocket_path = slave_parameter.get('websocket-path', '').strip('/') | urlencode %}
{%- if slave_type in ['notebook', 'websocket'] %}
{# websocket style needs http 1.1 max #}
{%- set enable_h2 = False %}
{%- endif %}
......@@ -72,7 +73,7 @@
if {>Accept-Encoding} not_match "(^gzip,.*|.*, gzip,.*|.*, gzip$|^gzip$)"
to {1}
}
{% elif slave_type != 'notebook' %}
{% elif slave_type not in ['notebook', 'websocket'] %}
rewrite {
regexp (.*)
to {1}
......@@ -182,6 +183,30 @@
without /proxy/
insecure_skip_verify
}
{%- elif slave_type == 'websocket' %}
{%- if websocket_path %}
proxy / {{ backend_url }} {
try_duration {{ slave_parameter['proxy_try_duration'] }}s
try_interval {{ slave_parameter['proxy_try_interval'] }}ms
transparent
insecure_skip_verify
}
proxy /{{ websocket_path }} {{ backend_url }} {
try_duration {{ slave_parameter['proxy_try_duration'] }}s
try_interval {{ slave_parameter['proxy_try_interval'] }}ms
transparent
insecure_skip_verify
websocket
}
{%- else %}
proxy / {{ backend_url }} {
try_duration {{ slave_parameter['proxy_try_duration'] }}s
try_interval {{ slave_parameter['proxy_try_interval'] }}ms
websocket
transparent
insecure_skip_verify
}
{%- endif %}
{%- else %} {#- if slave_type == 'zope' and backend_url #}
# Default configuration
{%- if default_path %}
......
......@@ -1090,6 +1090,15 @@ http://apachecustomhttpsaccepted.example.com:%%(http_port)s {
'url': cls.backend_url,
'type': 'notebook',
},
'type-websocket': {
'url': cls.backend_url,
'type': 'websocket',
},
'type-websocket-websocket-path': {
'url': cls.backend_url,
'type': 'websocket',
'websocket-path': '////ws////',
},
'type-eventsource': {
'url': cls.backend_url,
'type': 'eventsource',
......@@ -1207,9 +1216,9 @@ http://apachecustomhttpsaccepted.example.com:%%(http_port)s {
expected_parameter_dict = {
'monitor-base-url': None,
'domain': 'example.com',
'accepted-slave-amount': '44',
'accepted-slave-amount': '46',
'rejected-slave-amount': '4',
'slave-amount': '48',
'slave-amount': '50',
'kedifa-caucase-url': 'http://[%s]:%s' % (
SLAPOS_TEST_IPV6, CAUCASE_PORT),
'rejected-slave-dict': {
......@@ -2053,10 +2062,78 @@ http://apachecustomhttpsaccepted.example.com:%%(http_port)s {
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
@skip('Feature postponed')
def test_type_websocket(self):
# Pure websocket configurable frontend
raise NotImplementedError
parameter_dict = self.assertSlaveBase(
'type-websocket')
result = self.fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path',
headers={'Connection': 'Upgrade'})
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(
result,
'Path',
'/test-path'
)
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertEqual(
'Upgrade',
j['Incoming Headers']['connection']
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
def test_type_websocket_websocket_path(self):
parameter_dict = self.assertSlaveBase(
'type-websocket-websocket-path')
result = self.fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path',
headers={'Connection': 'Upgrade'})
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(
result,
'Path',
'/test-path'
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertFalse('connection' in j['Incoming Headers'].keys())
result = self.fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'ws/test-path',
headers={'Connection': 'Upgrade'})
self.assertEqualResultJson(
result,
'Path',
'/ws/test-path'
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertEqual(
'Upgrade',
j['Incoming Headers']['connection']
)
@skip('Feature postponed')
def test_type_eventsource(self):
......
......@@ -72,6 +72,10 @@ T-2/var/log/httpd/_type-notebook_access_log
T-2/var/log/httpd/_type-notebook_error_log
T-2/var/log/httpd/_type-redirect_access_log
T-2/var/log/httpd/_type-redirect_error_log
T-2/var/log/httpd/_type-websocket-websocket-path_access_log
T-2/var/log/httpd/_type-websocket-websocket-path_error_log
T-2/var/log/httpd/_type-websocket_access_log
T-2/var/log/httpd/_type-websocket_error_log
T-2/var/log/httpd/_type-zope-default-path_access_log
T-2/var/log/httpd/_type-zope-default-path_error_log
T-2/var/log/httpd/_type-zope-path_access_log
......
......@@ -80,6 +80,10 @@ T-2/etc/plugin/check-_type-notebook-error-log-last-day.py: OK
T-2/etc/plugin/check-_type-notebook-error-log-last-hour.py: OK
T-2/etc/plugin/check-_type-redirect-error-log-last-day.py: OK
T-2/etc/plugin/check-_type-redirect-error-log-last-hour.py: OK
T-2/etc/plugin/check-_type-websocket-error-log-last-day.py: OK
T-2/etc/plugin/check-_type-websocket-error-log-last-hour.py: OK
T-2/etc/plugin/check-_type-websocket-websocket-path-error-log-last-day.py: OK
T-2/etc/plugin/check-_type-websocket-websocket-path-error-log-last-hour.py: OK
T-2/etc/plugin/check-_type-zope-default-path-error-log-last-day.py: OK
T-2/etc/plugin/check-_type-zope-default-path-error-log-last-hour.py: OK
T-2/etc/plugin/check-_type-zope-error-log-last-day.py: OK
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment