summaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--test/go/404/app.go2
-rw-r--r--test/go/command_line_arguments/app.go2
-rw-r--r--test/go/cookies/app.go2
-rw-r--r--test/go/empty/app.go2
-rw-r--r--test/go/get_variables/app.go2
-rw-r--r--test/go/mirror/app.go2
-rw-r--r--test/go/ns_inspect/app.go4
-rw-r--r--test/go/post_variables/app.go2
-rw-r--r--test/go/variables/app.go2
-rw-r--r--test/python/user_group/wsgi.py18
-rw-r--r--test/test_go_isolation.py207
-rw-r--r--test/test_java_application.py21
-rw-r--r--test/test_node_application.py6
-rw-r--r--test/test_perl_application.py2
-rw-r--r--test/test_python_application.py97
-rw-r--r--test/test_python_environment.py16
-rw-r--r--test/test_routing.py2418
-rw-r--r--test/test_routing_tls.py6
-rw-r--r--test/test_ruby_application.py2
-rw-r--r--test/unit/applications/lang/go.py7
-rw-r--r--test/unit/applications/lang/java.py5
-rw-r--r--test/unit/applications/lang/node.py11
-rw-r--r--test/unit/applications/lang/perl.py5
-rw-r--r--test/unit/applications/lang/php.py5
-rw-r--r--test/unit/applications/lang/python.py5
-rw-r--r--test/unit/applications/lang/ruby.py5
-rw-r--r--test/unit/applications/proto.py14
-rw-r--r--test/unit/feature/isolation.py3
-rw-r--r--test/unit/http.py82
-rw-r--r--test/unit/main.py21
30 files changed, 1139 insertions, 1837 deletions
diff --git a/test/go/404/app.go b/test/go/404/app.go
index 08fe56c9..7eba2cf4 100644
--- a/test/go/404/app.go
+++ b/test/go/404/app.go
@@ -4,7 +4,7 @@ import (
"io"
"io/ioutil"
"net/http"
- "nginx/unit"
+ "unit.nginx.org/go"
)
func handler(w http.ResponseWriter, r *http.Request) {
diff --git a/test/go/command_line_arguments/app.go b/test/go/command_line_arguments/app.go
index 234e565e..1101e1cf 100644
--- a/test/go/command_line_arguments/app.go
+++ b/test/go/command_line_arguments/app.go
@@ -4,7 +4,7 @@ import (
"fmt"
"io"
"net/http"
- "nginx/unit"
+ "unit.nginx.org/go"
"os"
"strings"
)
diff --git a/test/go/cookies/app.go b/test/go/cookies/app.go
index e6647ea8..2216e153 100644
--- a/test/go/cookies/app.go
+++ b/test/go/cookies/app.go
@@ -2,7 +2,7 @@ package main
import (
"net/http"
- "nginx/unit"
+ "unit.nginx.org/go"
)
func handler(w http.ResponseWriter, r *http.Request) {
diff --git a/test/go/empty/app.go b/test/go/empty/app.go
index 6e0fce1b..9326a19b 100644
--- a/test/go/empty/app.go
+++ b/test/go/empty/app.go
@@ -2,7 +2,7 @@ package main
import (
"net/http"
- "nginx/unit"
+ "unit.nginx.org/go"
)
func handler(w http.ResponseWriter, r *http.Request) {}
diff --git a/test/go/get_variables/app.go b/test/go/get_variables/app.go
index 4dcc0e7b..1c0205a8 100644
--- a/test/go/get_variables/app.go
+++ b/test/go/get_variables/app.go
@@ -2,7 +2,7 @@ package main
import (
"net/http"
- "nginx/unit"
+ "unit.nginx.org/go"
)
func handler(w http.ResponseWriter, r *http.Request) {
diff --git a/test/go/mirror/app.go b/test/go/mirror/app.go
index 748aa7ee..78f047c3 100644
--- a/test/go/mirror/app.go
+++ b/test/go/mirror/app.go
@@ -4,7 +4,7 @@ import (
"fmt"
"io"
"net/http"
- "nginx/unit"
+ "unit.nginx.org/go"
)
func handler(w http.ResponseWriter, r *http.Request) {
diff --git a/test/go/ns_inspect/app.go b/test/go/ns_inspect/app.go
index ebecbb00..d9b561c9 100644
--- a/test/go/ns_inspect/app.go
+++ b/test/go/ns_inspect/app.go
@@ -4,7 +4,7 @@ import (
"encoding/json"
"fmt"
"net/http"
- "nginx/unit"
+ "unit.nginx.org/go"
"os"
"strconv"
)
@@ -70,6 +70,8 @@ func handler(w http.ResponseWriter, r *http.Request) {
return
}
+ w.Header().Add("Content-Type", "application/json")
+
w.Write(data)
}
diff --git a/test/go/post_variables/app.go b/test/go/post_variables/app.go
index 947976d2..e6279ac6 100644
--- a/test/go/post_variables/app.go
+++ b/test/go/post_variables/app.go
@@ -2,7 +2,7 @@ package main
import (
"net/http"
- "nginx/unit"
+ "unit.nginx.org/go"
)
func handler(w http.ResponseWriter, r *http.Request) {
diff --git a/test/go/variables/app.go b/test/go/variables/app.go
index fdcbf7e8..4be60cb7 100644
--- a/test/go/variables/app.go
+++ b/test/go/variables/app.go
@@ -4,7 +4,7 @@ import (
"fmt"
"io"
"net/http"
- "nginx/unit"
+ "unit.nginx.org/go"
)
func handler(w http.ResponseWriter, r *http.Request) {
diff --git a/test/python/user_group/wsgi.py b/test/python/user_group/wsgi.py
new file mode 100644
index 00000000..f5deb87d
--- /dev/null
+++ b/test/python/user_group/wsgi.py
@@ -0,0 +1,18 @@
+import json
+import os
+
+def application(environ, start_response):
+ uid = os.geteuid()
+ gid = os.getegid()
+
+ out = json.dumps({
+ 'UID': uid,
+ 'GID': gid,
+ }).encode('utf-8')
+
+ start_response('200 OK', [
+ ('Content-Length', str(len(out))),
+ ('Content-Type', 'application/json')
+ ])
+
+ return [out]
diff --git a/test/test_go_isolation.py b/test/test_go_isolation.py
index ee5ddf47..7884274d 100644
--- a/test/test_go_isolation.py
+++ b/test/test_go_isolation.py
@@ -1,4 +1,5 @@
-import os
+import pwd
+import grp
import json
import unittest
from unit.applications.lang.go import TestApplicationGo
@@ -18,20 +19,25 @@ class TestGoIsolation(TestApplicationGo):
return unit if not complete_check else unit.complete()
+ def unpriv_creds(self):
+ nobody_uid = pwd.getpwnam('nobody').pw_uid
+
+ try:
+ nogroup_gid = grp.getgrnam('nogroup').gr_gid
+ nogroup = 'nogroup'
+ except:
+ nogroup_gid = grp.getgrnam('nobody').gr_gid
+ nogroup = 'nobody'
+
+ return (nobody_uid, nogroup_gid, nogroup)
+
def isolation_key(self, key):
return key in self.available['features']['isolation'].keys()
- def conf_isolation(self, isolation):
- self.assertIn(
- 'success',
- self.conf(isolation, 'applications/ns_inspect/isolation'),
- 'configure isolation',
- )
-
def test_isolation_values(self):
self.load('ns_inspect')
- obj = self.isolation.parsejson(self.get()['body'])
+ obj = self.getjson()['body']
for ns, ns_value in self.available['features']['isolation'].items():
if ns.upper() in obj['NS']:
@@ -39,44 +45,155 @@ class TestGoIsolation(TestApplicationGo):
obj['NS'][ns.upper()], ns_value, '%s match' % ns
)
- def test_isolation_user(self):
+ def test_isolation_unpriv_user(self):
if not self.isolation_key('unprivileged_userns_clone'):
print('unprivileged clone is not available')
raise unittest.SkipTest()
+ if self.is_su:
+ print('privileged tests, skip this')
+ raise unittest.SkipTest()
+
self.load('ns_inspect')
- obj = self.isolation.parsejson(self.get()['body'])
+ obj = self.getjson()['body']
- self.assertTrue(obj['UID'] != 0, 'uid not zero')
- self.assertTrue(obj['GID'] != 0, 'gid not zero')
- self.assertEqual(obj['UID'], os.getuid(), 'uid match')
- self.assertEqual(obj['GID'], os.getgid(), 'gid match')
+ self.assertEqual(obj['UID'], self.uid, 'uid match')
+ self.assertEqual(obj['GID'], self.gid, 'gid match')
- self.conf_isolation({"namespaces": {"credential": True}})
+ self.load('ns_inspect', isolation={'namespaces': {'credential': True}})
- obj = self.isolation.parsejson(self.get()['body'])
+ obj = self.getjson()['body']
- # default uid and gid maps current user to nobody
- self.assertEqual(obj['UID'], 65534, 'uid nobody')
- self.assertEqual(obj['GID'], 65534, 'gid nobody')
+ nobody_uid, nogroup_gid, nogroup = self.unpriv_creds()
- self.conf_isolation(
- {
- "namespaces": {"credential": True},
- "uidmap": [
- {"container": 1000, "host": os.geteuid(), "size": 1}
- ],
- "gidmap": [
- {"container": 1000, "host": os.getegid(), "size": 1}
+ # unprivileged unit map itself to nobody in the container by default
+ self.assertEqual(obj['UID'], nobody_uid, 'uid of nobody')
+ self.assertEqual(obj['GID'], nogroup_gid, 'gid of %s' % nogroup)
+
+ self.load(
+ 'ns_inspect',
+ user='root',
+ isolation={'namespaces': {'credential': True}},
+ )
+
+ obj = self.getjson()['body']
+
+ self.assertEqual(obj['UID'], 0, 'uid match user=root')
+ self.assertEqual(obj['GID'], 0, 'gid match user=root')
+
+ self.load(
+ 'ns_inspect',
+ user='root',
+ group=nogroup,
+ isolation={'namespaces': {'credential': True}},
+ )
+
+ obj = self.getjson()['body']
+
+ self.assertEqual(obj['UID'], 0, 'uid match user=root group=nogroup')
+ self.assertEqual(
+ obj['GID'], nogroup_gid, 'gid match user=root group=nogroup'
+ )
+
+ self.load(
+ 'ns_inspect',
+ user='root',
+ group='root',
+ isolation={
+ 'namespaces': {'credential': True},
+ 'uidmap': [{'container': 0, 'host': self.uid, 'size': 1}],
+ 'gidmap': [{'container': 0, 'host': self.gid, 'size': 1}],
+ },
+ )
+
+ obj = self.getjson()['body']
+
+ self.assertEqual(obj['UID'], 0, 'uid match uidmap')
+ self.assertEqual(obj['GID'], 0, 'gid match gidmap')
+
+ def test_isolation_priv_user(self):
+ if not self.is_su:
+ print('unprivileged tests, skip this')
+ raise unittest.SkipTest()
+
+ self.load('ns_inspect')
+
+ nobody_uid, nogroup_gid, nogroup = self.unpriv_creds()
+
+ obj = self.getjson()['body']
+
+ self.assertEqual(obj['UID'], nobody_uid, 'uid match')
+ self.assertEqual(obj['GID'], nogroup_gid, 'gid match')
+
+ self.load('ns_inspect', isolation={'namespaces': {'credential': True}})
+
+ obj = self.getjson()['body']
+
+ # privileged unit map app creds in the container by default
+ self.assertEqual(obj['UID'], nobody_uid, 'uid nobody')
+ self.assertEqual(obj['GID'], nogroup_gid, 'gid nobody')
+
+ self.load(
+ 'ns_inspect',
+ user='root',
+ isolation={'namespaces': {'credential': True}},
+ )
+
+ obj = self.getjson()['body']
+
+ self.assertEqual(obj['UID'], 0, 'uid nobody user=root')
+ self.assertEqual(obj['GID'], 0, 'gid nobody user=root')
+
+ self.load(
+ 'ns_inspect',
+ user='root',
+ group=nogroup,
+ isolation={'namespaces': {'credential': True}},
+ )
+
+ obj = self.getjson()['body']
+
+ self.assertEqual(obj['UID'], 0, 'uid match user=root group=nogroup')
+ self.assertEqual(
+ obj['GID'], nogroup_gid, 'gid match user=root group=nogroup'
+ )
+
+ self.load(
+ 'ns_inspect',
+ user='root',
+ group='root',
+ isolation={
+ 'namespaces': {'credential': True},
+ 'uidmap': [{'container': 0, 'host': 0, 'size': 1}],
+ 'gidmap': [{'container': 0, 'host': 0, 'size': 1}],
+ },
+ )
+
+ obj = self.getjson()['body']
+
+ self.assertEqual(obj['UID'], 0, 'uid match uidmap user=root')
+ self.assertEqual(obj['GID'], 0, 'gid match gidmap user=root')
+
+ # map 65535 uids
+ self.load(
+ 'ns_inspect',
+ user='nobody',
+ isolation={
+ 'namespaces': {'credential': True},
+ 'uidmap': [
+ {'container': 0, 'host': 0, 'size': nobody_uid + 1}
],
- }
+ },
)
- obj = self.isolation.parsejson(self.get()['body'])
+ obj = self.getjson()['body']
- # default uid and gid maps current user to root
- self.assertEqual(obj['UID'], 1000, 'uid root')
- self.assertEqual(obj['GID'], 1000, 'gid root')
+ self.assertEqual(
+ obj['UID'], nobody_uid, 'uid match uidmap user=nobody'
+ )
+ self.assertEqual(
+ obj['GID'], nogroup_gid, 'gid match uidmap user=nobody'
+ )
def test_isolation_mnt(self):
if not self.isolation_key('mnt'):
@@ -87,12 +204,12 @@ class TestGoIsolation(TestApplicationGo):
print('unprivileged clone is not available')
raise unittest.SkipTest()
- self.load('ns_inspect')
- self.conf_isolation(
- {"namespaces": {"mount": True, "credential": True}}
+ self.load(
+ 'ns_inspect',
+ isolation={'namespaces': {'mount': True, 'credential': True}},
)
- obj = self.isolation.parsejson(self.get()['body'])
+ obj = self.getjson()['body']
# all but user and mnt
allns = list(self.available['features']['isolation'].keys())
@@ -119,14 +236,16 @@ class TestGoIsolation(TestApplicationGo):
print('pid namespace is not supported')
raise unittest.SkipTest()
- if not self.isolation_key('unprivileged_userns_clone'):
- print('unprivileged clone is not available')
+ if not (self.is_su or self.isolation_key('unprivileged_userns_clone')):
+ print('requires root or unprivileged_userns_clone')
raise unittest.SkipTest()
- self.load('ns_inspect')
- self.conf_isolation({"namespaces": {"pid": True, "credential": True}})
+ self.load(
+ 'ns_inspect',
+ isolation={'namespaces': {'pid': True, 'credential': True}},
+ )
- obj = self.isolation.parsejson(self.get()['body'])
+ obj = self.getjson()['body']
self.assertEqual(obj['PID'], 1, 'pid of container is 1')
@@ -150,9 +269,9 @@ class TestGoIsolation(TestApplicationGo):
else:
namespaces[ns] = False
- self.conf_isolation({"namespaces": namespaces})
+ self.load('ns_inspect', isolation={'namespaces': namespaces})
- obj = self.isolation.parsejson(self.get()['body'])
+ obj = self.getjson()['body']
for ns in allns:
if ns.upper() in obj['NS']:
diff --git a/test/test_java_application.py b/test/test_java_application.py
index 2e937718..d2b97f88 100644
--- a/test/test_java_application.py
+++ b/test/test_java_application.py
@@ -1,3 +1,4 @@
+import os
import time
import unittest
from unit.applications.lang.java import TestApplicationJava
@@ -1217,7 +1218,13 @@ class TestJavaApplication(TestApplicationJava):
def test_java_application_multipart(self):
self.load('multipart')
- body = """Preamble. Should be ignored.\r
+ reldst = '/uploads'
+ fulldst = self.testdir + reldst
+ os.mkdir(fulldst)
+ self.public_dir(fulldst)
+
+ body = (
+ """Preamble. Should be ignored.\r
\r
--12345\r
Content-Disposition: form-data; name="file"; filename="sample.txt"\r
@@ -1234,7 +1241,9 @@ Content-Disposition: form-data; name="upload"\r
Upload\r
--12345--\r
\r
-Epilogue. Should be ignored.""" % self.testdir
+Epilogue. Should be ignored."""
+ % fulldst
+ )
resp = self.post(
headers={
@@ -1246,9 +1255,13 @@ Epilogue. Should be ignored.""" % self.testdir
)
self.assertEqual(resp['status'], 200, 'multipart status')
- self.assertRegex(resp['body'], r'sample\.txt created', 'multipart body')
+ self.assertRegex(
+ resp['body'], r'sample\.txt created', 'multipart body'
+ )
self.assertIsNotNone(
- self.search_in_log(r'^Data from sample file$', name='sample.txt'),
+ self.search_in_log(
+ r'^Data from sample file$', name=reldst + '/sample.txt'
+ ),
'file created',
)
diff --git a/test/test_node_application.py b/test/test_node_application.py
index a5b4a108..b80d17d3 100644
--- a/test/test_node_application.py
+++ b/test/test_node_application.py
@@ -141,7 +141,7 @@ class TestNodeApplication(TestApplicationNode):
self.load('write_buffer')
self.assertEqual(
- self.get()['body'], '6\r\nbuffer\r\n0\r\n\r\n', 'write buffer'
+ self.get()['body'], 'buffer', 'write buffer'
)
def test_node_application_write_callback(self):
@@ -149,7 +149,7 @@ class TestNodeApplication(TestApplicationNode):
self.assertEqual(
self.get()['body'],
- '5\r\nhello\r\n5\r\nworld\r\n0\r\n\r\n',
+ 'helloworld',
'write callback order',
)
self.assertTrue(
@@ -173,7 +173,7 @@ class TestNodeApplication(TestApplicationNode):
self.assertEqual(
self.get()['body'],
- '4\r\nbody\r\n4\r\ntrue\r\n0\r\n\r\n',
+ 'bodytrue',
'write return',
)
diff --git a/test/test_perl_application.py b/test/test_perl_application.py
index bf3c65d5..a4bac623 100644
--- a/test/test_perl_application.py
+++ b/test/test_perl_application.py
@@ -157,7 +157,7 @@ class TestPerlApplication(TestApplicationPerl):
def test_perl_application_body_empty(self):
self.load('body_empty')
- self.assertEqual(self.get()['body'], '0\r\n\r\n', 'body empty')
+ self.assertEqual(self.get()['body'], '', 'body empty')
def test_perl_application_body_array(self):
self.load('body_array')
diff --git a/test/test_python_application.py b/test/test_python_application.py
index ae8f01ca..818816d0 100644
--- a/test/test_python_application.py
+++ b/test/test_python_application.py
@@ -1,4 +1,7 @@
import re
+import os
+import grp
+import pwd
import time
import unittest
from unit.applications.lang.python import TestApplicationPython
@@ -540,7 +543,7 @@ Connection: close
}
)
self.assertEqual(resp['status'], 200, 'status')
- self.assertEqual(resp['body'][-5:], '0\r\n\r\n', 'body')
+ self.assertEqual(resp['body'], 'XXXXXXX', 'body')
# Exception before start_response().
@@ -607,12 +610,11 @@ Connection: close
'X-Skip': '2',
'X-Chunked': '1',
'Connection': 'close',
- }
+ },
+ raw_resp=True
)
- if 'body' in resp:
- self.assertNotEqual(
- resp['body'][-5:], '0\r\n\r\n', 'incomplete body'
- )
+ if resp:
+ self.assertNotEqual(resp[-5:], '0\r\n\r\n', 'incomplete body')
self.assertEqual(
len(self.findall(r'Traceback')), 4, 'traceback count 4'
)
@@ -646,12 +648,11 @@ Connection: close
'X-Skip': '3',
'X-Chunked': '1',
'Connection': 'close',
- }
+ },
+ raw_resp=True
)
- if 'body' in resp:
- self.assertNotEqual(
- resp['body'][-5:], '0\r\n\r\n', 'incomplete body 2'
- )
+ if resp:
+ self.assertNotEqual(resp[-5:], '0\r\n\r\n', 'incomplete body 2')
self.assertEqual(
len(self.findall(r'Traceback')), 6, 'traceback count 6'
)
@@ -678,5 +679,79 @@ Connection: close
len(self.findall(r'Traceback')), 8, 'traceback count 8'
)
+ def test_python_user_group(self):
+ if not self.is_su:
+ print("requires root")
+ raise unittest.SkipTest()
+
+ nobody_uid = pwd.getpwnam('nobody').pw_uid
+
+ group = 'nobody'
+
+ try:
+ group_id = grp.getgrnam(group).gr_gid
+ except:
+ group = 'nogroup'
+ group_id = grp.getgrnam(group).gr_gid
+
+ self.load('user_group')
+
+ obj = self.getjson()['body']
+ self.assertEqual(obj['UID'], nobody_uid, 'nobody uid')
+ self.assertEqual(obj['GID'], group_id, 'nobody gid')
+
+ self.load('user_group', user='nobody')
+
+ obj = self.getjson()['body']
+ self.assertEqual(obj['UID'], nobody_uid, 'nobody uid user=nobody')
+ self.assertEqual(obj['GID'], group_id, 'nobody gid user=nobody')
+
+ self.load('user_group', user='nobody', group=group)
+
+ obj = self.getjson()['body']
+ self.assertEqual(
+ obj['UID'], nobody_uid, 'nobody uid user=nobody group=%s' % group
+ )
+
+ self.assertEqual(
+ obj['GID'], group_id, 'nobody gid user=nobody group=%s' % group
+ )
+
+ self.load('user_group', group=group)
+
+ obj = self.getjson()['body']
+ self.assertEqual(
+ obj['UID'], nobody_uid, 'nobody uid group=%s' % group
+ )
+
+ self.assertEqual(obj['GID'], group_id, 'nobody gid group=%s' % group)
+
+ self.load('user_group', user='root')
+
+ obj = self.getjson()['body']
+ self.assertEqual(obj['UID'], 0, 'root uid user=root')
+ self.assertEqual(obj['GID'], 0, 'root gid user=root')
+
+ group = 'root'
+
+ try:
+ grp.getgrnam(group)
+ group = True
+ except:
+ group = False
+
+ if group:
+ self.load('user_group', user='root', group='root')
+
+ obj = self.getjson()['body']
+ self.assertEqual(obj['UID'], 0, 'root uid user=root group=root')
+ self.assertEqual(obj['GID'], 0, 'root gid user=root group=root')
+
+ self.load('user_group', group='root')
+
+ obj = self.getjson()['body']
+ self.assertEqual(obj['UID'], nobody_uid, 'root uid group=root')
+ self.assertEqual(obj['GID'], 0, 'root gid group=root')
+
if __name__ == '__main__':
TestPythonApplication.main()
diff --git a/test/test_python_environment.py b/test/test_python_environment.py
index fe0baa13..f808f795 100644
--- a/test/test_python_environment.py
+++ b/test/test_python_environment.py
@@ -136,27 +136,27 @@ class TestPythonEnvironment(TestApplicationPython):
def test_python_environment_replace_default(self):
self.load('environment')
- pwd_default = self.get(
+ home_default = self.get(
headers={
'Host': 'localhost',
- 'X-Variables': 'PWD',
+ 'X-Variables': 'HOME',
'Connection': 'close',
}
)['body']
- self.assertGreater(len(pwd_default), 1, 'get default')
+ self.assertGreater(len(home_default), 1, 'get default')
- self.conf({"PWD": "new/pwd"}, 'applications/environment/environment')
+ self.conf({"HOME": "/"}, 'applications/environment/environment')
self.assertEqual(
self.get(
headers={
'Host': 'localhost',
- 'X-Variables': 'PWD',
+ 'X-Variables': 'HOME',
'Connection': 'close',
}
)['body'],
- 'new/pwd,',
+ '/,',
'replace default',
)
@@ -166,11 +166,11 @@ class TestPythonEnvironment(TestApplicationPython):
self.get(
headers={
'Host': 'localhost',
- 'X-Variables': 'PWD',
+ 'X-Variables': 'HOME',
'Connection': 'close',
}
)['body'],
- pwd_default,
+ home_default,
'restore default',
)
diff --git a/test/test_routing.py b/test/test_routing.py
index 2960f978..eb7b2fd8 100644
--- a/test/test_routing.py
+++ b/test/test_routing.py
@@ -45,409 +45,160 @@ class TestRouting(TestApplicationProto):
def route(self, route):
return self.conf([route], 'routes')
- def test_routes_match_method_positive(self):
- self.assertEqual(self.get()['status'], 200, 'method positive GET')
- self.assertEqual(self.post()['status'], 404, 'method positive POST')
-
- def test_routes_match_method_positive_many(self):
+ def route_match(self, match):
self.assertIn(
'success',
self.route(
- {
- "match": {"method": ["GET", "POST"]},
- "action": {"pass": "applications/empty"},
- }
+ {"match": match, "action": {"pass": "applications/empty"}}
),
- 'method positive many configure',
- )
-
- self.assertEqual(self.get()['status'], 200, 'method positive many GET')
- self.assertEqual(
- self.post()['status'], 200, 'method positive many POST'
- )
- self.assertEqual(
- self.delete()['status'], 404, 'method positive many DELETE'
+ 'route match configure',
)
- def test_routes_match_method_negative(self):
+ def route_match_invalid(self, match):
self.assertIn(
- 'success',
- self.route(
- {
- "match": {"method": "!GET"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'method negative configure',
- )
-
- self.assertEqual(self.get()['status'], 404, 'method negative GET')
- self.assertEqual(self.post()['status'], 200, 'method negative POST')
-
- def test_routes_match_method_negative_many(self):
- self.assertIn(
- 'success',
+ 'error',
self.route(
- {
- "match": {"method": ["!GET", "!POST"]},
- "action": {"pass": "applications/empty"},
- }
+ {"match": match, "action": {"pass": "applications/empty"}}
),
- 'method negative many configure',
+ 'route match configure invalid',
)
- self.assertEqual(self.get()['status'], 404, 'method negative many GET')
+ def host(self, host, status):
self.assertEqual(
- self.post()['status'], 404, 'method negative many POST'
+ self.get(headers={'Host': host, 'Connection': 'close'})[
+ 'status'
+ ],
+ status,
+ 'match host',
)
+
+ def cookie(self, cookie, status):
self.assertEqual(
- self.delete()['status'], 200, 'method negative many DELETE'
+ self.get(
+ headers={
+ 'Host': 'localhost',
+ 'Cookie': cookie,
+ 'Connection': 'close',
+ },
+ )['status'],
+ status,
+ 'match cookie',
)
- def test_routes_match_method_wildcard_left(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"method": "*ET"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'method wildcard left configure',
- )
+ def test_routes_match_method_positive(self):
+ self.assertEqual(self.get()['status'], 200, 'GET')
+ self.assertEqual(self.post()['status'], 404, 'POST')
- self.assertEqual(self.get()['status'], 200, 'method wildcard left GET')
- self.assertEqual(
- self.post()['status'], 404, 'method wildcard left POST'
- )
+ def test_routes_match_method_positive_many(self):
+ self.route_match({"method": ["GET", "POST"]})
- def test_routes_match_method_wildcard_right(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"method": "GE*"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'method wildcard right configure',
- )
+ self.assertEqual(self.get()['status'], 200, 'GET')
+ self.assertEqual(self.post()['status'], 200, 'POST')
+ self.assertEqual(self.delete()['status'], 404, 'DELETE')
- self.assertEqual(
- self.get()['status'], 200, 'method wildcard right GET'
- )
- self.assertEqual(
- self.post()['status'], 404, 'method wildcard right POST'
- )
+ def test_routes_match_method_negative(self):
+ self.route_match({"method": "!GET"})
- def test_routes_match_method_wildcard_left_right(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"method": "*GET*"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'method wildcard left right configure',
- )
+ self.assertEqual(self.get()['status'], 404, 'GET')
+ self.assertEqual(self.post()['status'], 200, 'POST')
- self.assertEqual(
- self.get()['status'], 200, 'method wildcard right GET'
- )
- self.assertEqual(
- self.post()['status'], 404, 'method wildcard right POST'
- )
+ def test_routes_match_method_negative_many(self):
+ self.route_match({"method": ["!GET", "!POST"]})
- def test_routes_match_method_wildcard(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"method": "*"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'method wildcard configure',
- )
+ self.assertEqual(self.get()['status'], 404, 'GET')
+ self.assertEqual(self.post()['status'], 404, 'POST')
+ self.assertEqual(self.delete()['status'], 200, 'DELETE')
- self.assertEqual(self.get()['status'], 200, 'method wildcard')
+ def test_routes_match_method_wildcard_left(self):
+ self.route_match({"method": "*ET"})
- def test_routes_match_invalid(self):
- self.assertIn(
- 'error',
- self.route(
- {
- "match": {"method": "**"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'wildcard invalid',
- )
+ self.assertEqual(self.get()['status'], 200, 'GET')
+ self.assertEqual(self.post()['status'], 404, 'POST')
- self.assertIn(
- 'error',
- self.route(
- {
- "match": {"method": "blah**"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'wildcard invalid 2',
- )
+ def test_routes_match_method_wildcard_right(self):
+ self.route_match({"method": "GE*"})
- self.assertIn(
- 'error',
- self.route(
- {
- "match": {"host": "*blah*blah"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'wildcard invalid 3',
- )
+ self.assertEqual(self.get()['status'], 200, 'GET')
+ self.assertEqual(self.post()['status'], 404, 'POST')
- self.assertIn(
- 'error',
- self.route(
- {
- "match": {"host": "blah*blah*blah"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'wildcard invalid 4',
- )
+ def test_routes_match_method_wildcard_left_right(self):
+ self.route_match({"method": "*GET*"})
- self.assertIn(
- 'error',
- self.route(
- {
- "match": {"host": "blah*blah*"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'wildcard invalid 5',
- )
+ self.assertEqual(self.get()['status'], 200, 'GET')
+ self.assertEqual(self.post()['status'], 404, 'POST')
- def test_routes_match_wildcard_middle(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"host": "ex*le"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'host wildcard middle configure',
- )
+ def test_routes_match_method_wildcard(self):
+ self.route_match({"method": "*"})
- self.assertEqual(
- self.get(headers={'Host': 'example', 'Connection': 'close'})[
- 'status'
- ],
- 200,
- 'host wildcard middle',
- )
+ self.assertEqual(self.get()['status'], 200, 'GET')
- self.assertEqual(
- self.get(headers={'Host': 'www.example', 'Connection': 'close'})[
- 'status'
- ],
- 404,
- 'host wildcard middle 2',
- )
+ def test_routes_match_invalid(self):
+ self.route_match_invalid({"method": "**"})
+ self.route_match_invalid({"method": "blah**"})
+ self.route_match_invalid({"host": "*blah*blah"})
+ self.route_match_invalid({"host": "blah*blah*blah"})
+ self.route_match_invalid({"host": "blah*blah*"})
- self.assertEqual(
- self.get(headers={'Host': 'example.com', 'Connection': 'close'})[
- 'status'
- ],
- 404,
- 'host wildcard middle 3',
- )
+ def test_routes_match_wildcard_middle(self):
+ self.route_match({"host": "ex*le"})
- self.assertEqual(
- self.get(headers={'Host': 'exampl', 'Connection': 'close'})[
- 'status'
- ],
- 404,
- 'host wildcard middle 4',
- )
+ self.host('example', 200)
+ self.host('www.example', 404)
+ self.host('example.com', 404)
+ self.host('exampl', 404)
def test_routes_match_method_case_insensitive(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"method": "get"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'method case insensitive configure',
- )
+ self.route_match({"method": "get"})
- self.assertEqual(self.get()['status'], 200, 'method case insensitive')
+ self.assertEqual(self.get()['status'], 200, 'GET')
def test_routes_match_wildcard_left_case_insensitive(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"method": "*et"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match wildcard case insensitive configure',
- )
+ self.route_match({"method": "*get"})
+ self.assertEqual(self.get()['status'], 200, 'GET')
- self.assertEqual(
- self.get()['status'], 200, 'match wildcard case insensitive'
- )
+ self.route_match({"method": "*et"})
+ self.assertEqual(self.get()['status'], 200, 'GET')
def test_routes_match_wildcard_middle_case_insensitive(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"method": "g*t"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match wildcard case insensitive configure',
- )
+ self.route_match({"method": "g*t"})
- self.assertEqual(
- self.get()['status'], 200, 'match wildcard case insensitive'
- )
+ self.assertEqual(self.get()['status'], 200, 'GET')
def test_routes_match_wildcard_right_case_insensitive(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"method": "get*"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match wildcard case insensitive configure',
- )
+ self.route_match({"method": "get*"})
+ self.assertEqual(self.get()['status'], 200, 'GET')
- self.assertEqual(
- self.get()['status'], 200, 'match wildcard case insensitive'
- )
+ self.route_match({"method": "ge*"})
+ self.assertEqual(self.get()['status'], 200, 'GET')
def test_routes_match_wildcard_substring_case_insensitive(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"method": "*et*"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match wildcard substring case insensitive configure',
- )
+ self.route_match({"method": "*et*"})
- self.assertEqual(
- self.get()['status'],
- 200,
- 'match wildcard substring case insensitive',
- )
+ self.assertEqual(self.get()['status'], 200, 'GET')
def test_routes_match_wildcard_left_case_sensitive(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"uri": "*blah"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match wildcard left case sensitive configure',
- )
+ self.route_match({"uri": "*blah"})
- self.assertEqual(
- self.get(url='/blah')['status'],
- 200,
- 'match wildcard left case sensitive /blah',
- )
-
- self.assertEqual(
- self.get(url='/BLAH')['status'],
- 404,
- 'match wildcard left case sensitive /BLAH',
- )
+ self.assertEqual(self.get(url='/blah')['status'], 200, '/blah')
+ self.assertEqual(self.get(url='/BLAH')['status'], 404, '/BLAH')
def test_routes_match_wildcard_middle_case_sensitive(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"uri": "/b*h"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match wildcard middle case sensitive configure',
- )
+ self.route_match({"uri": "/b*h"})
- self.assertEqual(
- self.get(url='/blah')['status'],
- 200,
- 'match wildcard middle case sensitive /blah',
- )
-
- self.assertEqual(
- self.get(url='/BLAH')['status'],
- 404,
- 'match wildcard middle case sensitive /BLAH',
- )
+ self.assertEqual(self.get(url='/blah')['status'], 200, '/blah')
+ self.assertEqual(self.get(url='/BLAH')['status'], 404, '/BLAH')
def test_routes_match_wildcard_right_case_sensitive(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"uri": "/bla*"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match wildcard right case sensitive configure',
- )
-
- self.assertEqual(
- self.get(url='/blah')['status'],
- 200,
- 'match wildcard right case sensitive /blah',
- )
+ self.route_match({"uri": "/bla*"})
- self.assertEqual(
- self.get(url='/BLAH')['status'],
- 404,
- 'match wildcard right case sensitive /BLAH',
- )
+ self.assertEqual(self.get(url='/blah')['status'], 200, '/blah')
+ self.assertEqual(self.get(url='/BLAH')['status'], 404, '/BLAH')
def test_routes_match_wildcard_substring_case_sensitive(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"uri": "*bla*"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match wildcard substring case sensitive configure',
- )
-
- self.assertEqual(
- self.get(url='/blah')['status'],
- 200,
- 'match wildcard substring case sensitive /blah',
- )
+ self.route_match({"uri": "*bla*"})
- self.assertEqual(
- self.get(url='/BLAH')['status'],
- 404,
- 'match wildcard substring case sensitive /BLAH',
- )
+ self.assertEqual(self.get(url='/blah')['status'], 200, '/blah')
+ self.assertEqual(self.get(url='/BLAH')['status'], 404, '/BLAH')
def test_routes_absent(self):
self.conf(
@@ -616,65 +367,18 @@ class TestRouting(TestApplicationProto):
self.assertEqual(self.get()['status'], 200, 'routes two')
def test_routes_match_host_positive(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"host": "localhost"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match host positive configure',
- )
-
- self.assertEqual(
- self.get()['status'], 200, 'match host positive localhost'
- )
-
- self.assertEqual(
- self.get(headers={'Host': 'localhost.', 'Connection': 'close'})[
- 'status'
- ],
- 200,
- 'match host positive trailing dot',
- )
-
- self.assertEqual(
- self.get(headers={'Host': 'www.localhost', 'Connection': 'close'})[
- 'status'
- ],
- 404,
- 'match host positive www.localhost',
- )
-
- self.assertEqual(
- self.get(headers={'Host': 'localhost1', 'Connection': 'close'})[
- 'status'
- ],
- 404,
- 'match host positive localhost1',
- )
+ self.route_match({"host": "localhost"})
- self.assertEqual(
- self.get(headers={'Host': 'example.com', 'Connection': 'close'})[
- 'status'
- ],
- 404,
- 'match host positive example.com',
- )
+ self.assertEqual(self.get()['status'], 200, 'localhost')
+ self.host('localhost.', 200)
+ self.host('localhost.', 200)
+ self.host('.localhost', 404)
+ self.host('www.localhost', 404)
+ self.host('localhost1', 404)
@unittest.skip('not yet')
def test_routes_match_host_absent(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"host": "localhost"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match host absent configure',
- )
+ self.route_match({"host": "localhost"})
self.assertEqual(
self.get(headers={'Connection': 'close'})['status'],
@@ -683,212 +387,52 @@ class TestRouting(TestApplicationProto):
)
def test_routes_match_host_ipv4(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"host": "127.0.0.1"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match host ipv4 configure',
- )
+ self.route_match({"host": "127.0.0.1"})
- self.assertEqual(
- self.get(headers={'Host': '127.0.0.1', 'Connection': 'close'})[
- 'status'
- ],
- 200,
- 'match host ipv4',
- )
+ self.host('127.0.0.1', 200)
+ self.host('127.0.0.1:7080', 200)
def test_routes_match_host_ipv6(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"host": "[::1]"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match host ipv6 configure',
- )
+ self.route_match({"host": "[::1]"})
- self.assertEqual(
- self.get(headers={'Host': '[::1]', 'Connection': 'close'})[
- 'status'
- ],
- 200,
- 'match host ipv6',
- )
-
- self.assertEqual(
- self.get(headers={'Host': '[::1]:7080', 'Connection': 'close'})[
- 'status'
- ],
- 200,
- 'match host ipv6 port',
- )
+ self.host('[::1]', 200)
+ self.host('[::1]:7080', 200)
def test_routes_match_host_positive_many(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"host": ["localhost", "example.com"]},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match host positive many configure',
- )
-
- self.assertEqual(
- self.get()['status'], 200, 'match host positive many localhost'
- )
+ self.route_match({"host": ["localhost", "example.com"]})
- self.assertEqual(
- self.get(headers={'Host': 'example.com', 'Connection': 'close'})[
- 'status'
- ],
- 200,
- 'match host positive many example.com',
- )
+ self.assertEqual(self.get()['status'], 200, 'localhost')
+ self.host('example.com', 200)
def test_routes_match_host_positive_and_negative(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"host": ["*example.com", "!www.example.com"]},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match host positive and negative configure',
- )
+ self.route_match({"host": ["*example.com", "!www.example.com"]})
- self.assertEqual(
- self.get()['status'],
- 404,
- 'match host positive and negative localhost',
- )
-
- self.assertEqual(
- self.get(headers={'Host': 'example.com', 'Connection': 'close'})[
- 'status'
- ],
- 200,
- 'match host positive and negative example.com',
- )
-
- self.assertEqual(
- self.get(
- headers={'Host': 'www.example.com', 'Connection': 'close'}
- )['status'],
- 404,
- 'match host positive and negative www.example.com',
- )
-
- self.assertEqual(
- self.get(
- headers={'Host': '!www.example.com', 'Connection': 'close'}
- )['status'],
- 200,
- 'match host positive and negative !www.example.com',
- )
+ self.assertEqual(self.get()['status'], 404, 'localhost')
+ self.host('example.com', 200)
+ self.host('www.example.com', 404)
+ self.host('!www.example.com', 200)
def test_routes_match_host_positive_and_negative_wildcard(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"host": ["*example*", "!www.example*"]},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match host positive and negative wildcard configure',
- )
+ self.route_match({"host": ["*example*", "!www.example*"]})
- self.assertEqual(
- self.get(headers={'Host': 'example.com', 'Connection': 'close'})[
- 'status'
- ],
- 200,
- 'match host positive and negative wildcard example.com',
- )
-
- self.assertEqual(
- self.get(
- headers={'Host': 'www.example.com', 'Connection': 'close'}
- )['status'],
- 404,
- 'match host positive and negative wildcard www.example.com',
- )
+ self.host('example.com', 200)
+ self.host('www.example.com', 404)
def test_routes_match_host_case_insensitive(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"host": "Example.com"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'host case insensitive configure',
- )
+ self.route_match({"host": "Example.com"})
- self.assertEqual(
- self.get(headers={'Host': 'example.com', 'Connection': 'close'})[
- 'status'
- ],
- 200,
- 'host case insensitive example.com',
- )
-
- self.assertEqual(
- self.get(headers={'Host': 'EXAMPLE.COM', 'Connection': 'close'})[
- 'status'
- ],
- 200,
- 'host case insensitive EXAMPLE.COM',
- )
+ self.host('example.com', 200)
+ self.host('EXAMPLE.COM', 200)
def test_routes_match_host_port(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"host": "example.com"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match host port configure',
- )
+ self.route_match({"host": "example.com"})
- self.assertEqual(
- self.get(
- headers={'Host': 'example.com:7080', 'Connection': 'close'}
- )['status'],
- 200,
- 'match host port',
- )
+ self.host('example.com:7080', 200)
def test_routes_match_host_empty(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"host": ""},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match host empty configure',
- )
+ self.route_match({"host": ""})
- self.assertEqual(
- self.get(headers={'Host': '', 'Connection': 'close'})['status'],
- 200,
- 'match host empty',
- )
+ self.host('', 200)
self.assertEqual(
self.get(http_10=True, headers={})['status'],
200,
@@ -897,160 +441,80 @@ class TestRouting(TestApplicationProto):
self.assertEqual(self.get()['status'], 404, 'match host empty 3')
def test_routes_match_uri_positive(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"uri": ["/blah", "/slash/"]},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match uri positive configure',
- )
+ self.route_match({"uri": ["/blah", "/slash/"]})
- self.assertEqual(self.get()['status'], 404, 'match uri positive')
- self.assertEqual(
- self.get(url='/blah')['status'], 200, 'match uri positive blah'
- )
- self.assertEqual(
- self.get(url='/blah#foo')['status'],
- 200,
- 'match uri positive #foo',
- )
- self.assertEqual(
- self.get(url='/blah?var')['status'], 200, 'match uri args'
- )
- self.assertEqual(
- self.get(url='//blah')['status'], 200, 'match uri adjacent slashes'
- )
- self.assertEqual(
- self.get(url='/slash/foo/../')['status'],
- 200,
- 'match uri relative path',
- )
+ self.assertEqual(self.get()['status'], 404, '/')
+ self.assertEqual(self.get(url='/blah')['status'], 200, '/blah')
+ self.assertEqual(self.get(url='/blah#foo')['status'], 200, '/blah#foo')
+ self.assertEqual(self.get(url='/blah?var')['status'], 200, '/blah?var')
+ self.assertEqual(self.get(url='//blah')['status'], 200, '//blah')
self.assertEqual(
- self.get(url='/slash/./')['status'],
- 200,
- 'match uri relative path 2',
- )
- self.assertEqual(
- self.get(url='/slash//.//')['status'],
- 200,
- 'match uri adjacent slashes 2',
- )
- self.assertEqual(
- self.get(url='/%')['status'], 400, 'match uri percent'
+ self.get(url='/slash/foo/../')['status'], 200, 'relative'
)
+ self.assertEqual(self.get(url='/slash/./')['status'], 200, '/slash/./')
self.assertEqual(
- self.get(url='/%1')['status'], 400, 'match uri percent digit'
+ self.get(url='/slash//.//')['status'], 200, 'adjacent slashes'
)
+ self.assertEqual(self.get(url='/%')['status'], 400, 'percent')
+ self.assertEqual(self.get(url='/%1')['status'], 400, 'percent digit')
+ self.assertEqual(self.get(url='/%A')['status'], 400, 'percent letter')
self.assertEqual(
- self.get(url='/%A')['status'], 400, 'match uri percent letter'
+ self.get(url='/slash/.?args')['status'], 200, 'dot args'
)
self.assertEqual(
- self.get(url='/slash/.?args')['status'], 200, 'match uri dot args'
- )
- self.assertEqual(
- self.get(url='/slash/.#frag')['status'], 200, 'match uri dot frag'
+ self.get(url='/slash/.#frag')['status'], 200, 'dot frag'
)
self.assertEqual(
self.get(url='/slash/foo/..?args')['status'],
200,
- 'match uri dot dot args',
+ 'dot dot args',
)
self.assertEqual(
self.get(url='/slash/foo/..#frag')['status'],
200,
- 'match uri dot dot frag',
+ 'dot dot frag',
)
self.assertEqual(
- self.get(url='/slash/.')['status'], 200, 'match uri trailing dot'
+ self.get(url='/slash/.')['status'], 200, 'trailing dot'
)
self.assertEqual(
self.get(url='/slash/foo/..')['status'],
200,
- 'match uri trailing dot dot',
+ 'trailing dot dot',
)
def test_routes_match_uri_case_sensitive(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"uri": "/BLAH"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match uri case sensitive configure',
- )
+ self.route_match({"uri": "/BLAH"})
- self.assertEqual(
- self.get(url='/blah')['status'],
- 404,
- 'match uri case sensitive blah',
- )
- self.assertEqual(
- self.get(url='/BlaH')['status'],
- 404,
- 'match uri case sensitive BlaH',
- )
- self.assertEqual(
- self.get(url='/BLAH')['status'],
- 200,
- 'match uri case sensitive BLAH',
- )
+ self.assertEqual(self.get(url='/blah')['status'], 404, '/blah')
+ self.assertEqual(self.get(url='/BlaH')['status'], 404, '/BlaH')
+ self.assertEqual(self.get(url='/BLAH')['status'], 200, '/BLAH')
def test_routes_match_uri_normalize(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"uri": "/blah"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match uri normalize configure',
- )
+ self.route_match({"uri": "/blah"})
self.assertEqual(
- self.get(url='/%62%6c%61%68')['status'], 200, 'match uri normalize'
+ self.get(url='/%62%6c%61%68')['status'], 200, 'normalize'
)
def test_routes_match_empty_array(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"uri": []},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match empty array configure',
- )
+ self.route_match({"uri": []})
- self.assertEqual(
- self.get(url='/blah')['status'],
- 200,
- 'match empty array',
- )
+ self.assertEqual(self.get(url='/blah')['status'], 200, 'empty array')
def test_routes_reconfigure(self):
- self.assertIn('success', self.conf([], 'routes'), 'routes redefine')
- self.assertEqual(self.get()['status'], 404, 'routes redefine request')
+ self.assertIn('success', self.conf([], 'routes'), 'redefine')
+ self.assertEqual(self.get()['status'], 404, 'redefine request')
self.assertIn(
'success',
self.conf([{"action": {"pass": "applications/empty"}}], 'routes'),
- 'routes redefine 2',
- )
- self.assertEqual(
- self.get()['status'], 200, 'routes redefine request 2'
+ 'redefine 2',
)
+ self.assertEqual(self.get()['status'], 200, 'redefine request 2')
- self.assertIn('success', self.conf([], 'routes'), 'routes redefine 3')
- self.assertEqual(
- self.get()['status'], 404, 'routes redefine request 3'
- )
+ self.assertIn('success', self.conf([], 'routes'), 'redefine 3')
+ self.assertEqual(self.get()['status'], 404, 'redefine request 3')
self.assertIn(
'success',
@@ -1072,63 +536,46 @@ class TestRouting(TestApplicationProto):
},
}
),
- 'routes redefine 4',
- )
- self.assertEqual(
- self.get()['status'], 200, 'routes redefine request 4'
+ 'redefine 4',
)
+ self.assertEqual(self.get()['status'], 200, 'redefine request 4')
self.assertIn(
- 'success', self.conf_delete('routes/main/0'), 'routes redefine 5'
- )
- self.assertEqual(
- self.get()['status'], 404, 'routes redefine request 5'
+ 'success', self.conf_delete('routes/main/0'), 'redefine 5'
)
+ self.assertEqual(self.get()['status'], 404, 'redefine request 5')
self.assertIn(
'success',
self.conf_post(
{"action": {"pass": "applications/empty"}}, 'routes/main'
),
- 'routes redefine 6',
- )
- self.assertEqual(
- self.get()['status'], 200, 'routes redefine request 6'
+ 'redefine 6',
)
+ self.assertEqual(self.get()['status'], 200, 'redefine request 6')
self.assertIn(
'error',
self.conf(
{"action": {"pass": "applications/empty"}}, 'routes/main/2'
),
- 'routes redefine 7',
+ 'redefine 7',
)
self.assertIn(
'success',
self.conf(
{"action": {"pass": "applications/empty"}}, 'routes/main/1'
),
- 'routes redefine 8',
+ 'redefine 8',
)
self.assertEqual(
- len(self.conf_get('routes/main')), 2, 'routes redefine conf 8'
- )
- self.assertEqual(
- self.get()['status'], 200, 'routes redefine request 8'
+ len(self.conf_get('routes/main')), 2, 'redefine conf 8'
)
+ self.assertEqual(self.get()['status'], 200, 'redefine request 8')
def test_routes_edit(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"method": "GET"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'routes edit configure',
- )
+ self.route_match({"method": "GET"})
self.assertEqual(self.get()['status'], 200, 'routes edit GET')
self.assertEqual(self.post()['status'], 404, 'routes edit POST')
@@ -1260,16 +707,7 @@ class TestRouting(TestApplicationProto):
def test_match_edit(self):
self.skip_alerts.append(r'failed to apply new conf')
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"method": ["GET", "POST"]},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match edit configure',
- )
+ self.route_match({"method": ["GET", "POST"]})
self.assertEqual(self.get()['status'], 200, 'match edit GET')
self.assertEqual(self.post()['status'], 200, 'match edit POST')
@@ -1390,20 +828,7 @@ class TestRouting(TestApplicationProto):
self.assertEqual(self.get()['status'], 200, 'match edit GET 8')
def test_routes_match_rules(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {
- "method": "GET",
- "host": "localhost",
- "uri": "/",
- },
- "action": {"pass": "applications/empty"},
- }
- ),
- 'routes match rules configure',
- )
+ self.route_match({"method": "GET", "host": "localhost", "uri": "/"})
self.assertEqual(self.get()['status'], 200, 'routes match rules')
@@ -1417,75 +842,18 @@ class TestRouting(TestApplicationProto):
self.assertEqual(self.get()['status'], 500, 'routes loop')
def test_routes_match_headers(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"headers": {"host": "localhost"}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match headers configure',
- )
+ self.route_match({"headers": {"host": "localhost"}})
self.assertEqual(self.get()['status'], 200, 'match headers')
- self.assertEqual(
- self.get(
- headers={
- "Host": "Localhost",
- "Connection": "close",
- }
- )['status'],
- 200,
- 'match headers case insensitive',
- )
- self.assertEqual(
- self.get(
- headers={
- "Host": "localhost.com",
- "Connection": "close",
- }
- )['status'],
- 404,
- 'match headers exact',
- )
- self.assertEqual(
- self.get(
- headers={
- "Host": "llocalhost",
- "Connection": "close",
- }
- )['status'],
- 404,
- 'match headers exact 2',
- )
- self.assertEqual(
- self.get(
- headers={
- "Host": "host",
- "Connection": "close",
- }
- )['status'],
- 404,
- 'match headers exact 3',
- )
+ self.host('Localhost', 200)
+ self.host('localhost.com', 404)
+ self.host('llocalhost', 404)
+ self.host('host', 404)
def test_routes_match_headers_multiple(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {
- "headers": {"host": "localhost", "x-blah": "test"}
- },
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match headers multiple configure',
- )
+ self.route_match({"headers": {"host": "localhost", "x-blah": "test"}})
self.assertEqual(self.get()['status'], 404, 'match headers multiple')
-
self.assertEqual(
self.get(
headers={
@@ -1511,16 +879,7 @@ class TestRouting(TestApplicationProto):
)
def test_routes_match_headers_multiple_values(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"headers": {"x-blah": "test"}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match headers multiple values configure',
- )
+ self.route_match({"headers": {"x-blah": "test"}})
self.assertEqual(
self.get(
@@ -1557,21 +916,11 @@ class TestRouting(TestApplicationProto):
)
def test_routes_match_headers_multiple_rules(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"headers": {"x-blah": ["test", "blah"]}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match headers multiple rules configure',
- )
+ self.route_match({"headers": {"x-blah": ["test", "blah"]}})
self.assertEqual(
self.get()['status'], 404, 'match headers multiple rules'
)
-
self.assertEqual(
self.get(
headers={
@@ -1583,7 +932,6 @@ class TestRouting(TestApplicationProto):
200,
'match headers multiple rules 2',
)
-
self.assertEqual(
self.get(
headers={
@@ -1595,7 +943,6 @@ class TestRouting(TestApplicationProto):
200,
'match headers multiple rules 3',
)
-
self.assertEqual(
self.get(
headers={
@@ -1621,16 +968,7 @@ class TestRouting(TestApplicationProto):
)
def test_routes_match_headers_case_insensitive(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"headers": {"X-BLAH": "TEST"}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match headers case insensitive configure',
- )
+ self.route_match({"headers": {"X-BLAH": "TEST"}})
self.assertEqual(
self.get(
@@ -1645,104 +983,27 @@ class TestRouting(TestApplicationProto):
)
def test_routes_match_headers_invalid(self):
- self.assertIn(
- 'error',
- self.route(
- {
- "match": {"headers": ["blah"]},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match headers invalid',
- )
-
- self.assertIn(
- 'error',
- self.route(
- {
- "match": {"headers": {"foo": ["bar", {}]}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match headers invalid 2',
- )
+ self.route_match_invalid({"headers": ["blah"]})
+ self.route_match_invalid({"headers": {"foo": ["bar", {}]}})
+ self.route_match_invalid({"headers": {"": "blah"}})
def test_routes_match_headers_empty_rule(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"headers": {"host": ""}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match headers empty rule configure',
- )
-
- self.assertEqual(self.get()['status'], 404, 'match headers empty rule')
-
- self.assertEqual(
- self.get(headers={"Host": "", "Connection": "close"})['status'],
- 200,
- 'match headers empty rule 2',
- )
+ self.route_match({"headers": {"host": ""}})
- def test_routes_match_headers_rule_field_empty(self):
- self.assertIn(
- 'error',
- self.route(
- {
- "match": {"headers": {"": "blah"}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match headers rule field empty configure',
- )
+ self.assertEqual(self.get()['status'], 404, 'localhost')
+ self.host('', 200)
def test_routes_match_headers_empty(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"headers": {}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match headers empty configure',
- )
-
- self.assertEqual(self.get()['status'], 200, 'match headers empty')
+ self.route_match({"headers": {}})
+ self.assertEqual(self.get()['status'], 200, 'empty')
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"headers": []},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match headers array empty configure 2',
- )
-
- self.assertEqual(
- self.get()['status'], 200, 'match headers array empty 2'
- )
+ self.route_match({"headers": []})
+ self.assertEqual(self.get()['status'], 200, 'empty 2')
def test_routes_match_headers_rule_array_empty(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"headers": {"blah": []}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match headers rule array empty configure',
- )
+ self.route_match({"headers": {"blah": []}})
- self.assertEqual(
- self.get()['status'], 404, 'match headers rule array empty'
- )
+ self.assertEqual(self.get()['status'], 404, 'array empty')
self.assertEqual(
self.get(
headers={
@@ -1754,22 +1015,15 @@ class TestRouting(TestApplicationProto):
)
def test_routes_match_headers_array(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {
- "headers": [
- {"x-header1": "foo*"},
- {"x-header2": "bar"},
- {"x-header3": ["foo", "bar"]},
- {"x-header1": "bar", "x-header4": "foo"},
- ]
- },
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match headers array configure',
+ self.route_match(
+ {
+ "headers": [
+ {"x-header1": "foo*"},
+ {"x-header2": "bar"},
+ {"x-header3": ["foo", "bar"]},
+ {"x-header1": "bar", "x-header4": "foo"},
+ ]
+ }
)
self.assertEqual(self.get()['status'], 404, 'match headers array')
@@ -1860,352 +1114,128 @@ class TestRouting(TestApplicationProto):
)
def test_routes_match_arguments(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"arguments": {"foo": "bar"}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match arguments configure',
- )
+ self.route_match({"arguments": {"foo": "bar"}})
- self.assertEqual(self.get()['status'], 404, 'match arguments')
- self.assertEqual(
- self.get(url='/?foo=bar')['status'], 200, 'match arguments 2'
- )
-
- self.assertEqual(
- self.get(url='/?Foo=bar')['status'],
- 404,
- 'match arguments case sensitive',
- )
- self.assertEqual(
- self.get(url='/?foo=Bar')['status'],
- 404,
- 'match arguments case sensitive 2',
- )
- self.assertEqual(
- self.get(url='/?foo=bar1')['status'],
- 404,
- 'match arguments exact',
- )
- self.assertEqual(
- self.get(url='/?1foo=bar')['status'],
- 404,
- 'match arguments exact 2',
- )
+ self.assertEqual(self.get()['status'], 404, 'args')
+ self.assertEqual(self.get(url='/?foo=bar')['status'], 200, 'args 2')
+ self.assertEqual(self.get(url='/?foo=bar1')['status'], 404, 'args 3')
+ self.assertEqual(self.get(url='/?1foo=bar')['status'], 404, 'args 4')
+ self.assertEqual(self.get(url='/?Foo=bar')['status'], 404, 'case')
+ self.assertEqual(self.get(url='/?foo=Bar')['status'], 404, 'case 2')
def test_routes_match_arguments_empty(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"arguments": {}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match arguments empty configure',
- )
+ self.route_match({"arguments": {}})
+ self.assertEqual(self.get()['status'], 200, 'arguments empty')
- self.assertEqual(self.get()['status'], 200, 'match arguments empty')
-
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"arguments": []},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match arguments empty configure 2',
- )
-
- self.assertEqual(self.get()['status'], 200, 'match arguments empty 2')
+ self.route_match({"arguments": []})
+ self.assertEqual(self.get()['status'], 200, 'arguments empty 2')
def test_routes_match_arguments_invalid(self):
- self.assertIn(
- 'error',
- self.route(
- {
- "match": {"arguments": ["var"]},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match arguments invalid',
- )
-
- self.assertIn(
- 'error',
- self.route(
- {
- "match": {"arguments": [{"var1": {}}]},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match arguments invalid 2',
- )
-
- self.assertIn(
- 'error',
- self.route(
- {
- "match": {"arguments": {"": "bar"}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match arguments invalid 3',
- )
+ self.route_match_invalid({"arguments": ["var"]})
+ self.route_match_invalid({"arguments": [{"var1": {}}]})
+ self.route_match_invalid({"arguments": {"": "bar"}})
@unittest.skip('not yet')
def test_routes_match_arguments_space(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"arguments": {"foo": "bar "}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match arguments space configure',
- )
+ self.route_match({"arguments": {"foo": "bar "}})
- self.assertEqual(
- self.get(url='/?foo=bar &')['status'],
- 200,
- 'match arguments space',
- )
- self.assertEqual(
- self.get(url='/?foo=bar+&')['status'],
- 200,
- 'match arguments space 2',
- ) # FAIL
- self.assertEqual(
- self.get(url='/?foo=bar%20&')['status'],
- 200,
- 'match arguments space 3',
- ) # FAIL
+ self.assertEqual(self.get(url='/?foo=bar &')['status'], 200, 'sp')
+ # FAIL
+ self.assertEqual(self.get(url='/?foo=bar+&')['status'], 200, 'sp 2')
+ # FAIL
+ self.assertEqual(self.get(url='/?foo=bar%20&')['status'], 200, 'sp 3')
@unittest.skip('not yet')
def test_routes_match_arguments_plus(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"arguments": [{"foo": "bar+"}]},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match arguments plus configure',
- )
+ self.route_match({"arguments": [{"foo": "bar+"}]})
+ self.assertEqual(self.get(url='/?foo=bar+&')['status'], 200, 'plus')
+ # FAIL
self.assertEqual(
- self.get(url='/?foo=bar+&')['status'],
- 200,
- 'match arguments plus',
+ self.get(url='/?foo=bar%2B&')['status'], 200, 'plus 2'
)
- self.assertEqual(
- self.get(url='/?foo=bar%2B&')['status'],
- 200,
- 'match arguments plus 2',
- ) # FAIL
@unittest.skip('not yet')
def test_routes_match_arguments_hex(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"arguments": [{"foo": "bar"}]},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match arguments hex configure',
- )
+ self.route_match({"arguments": [{"foo": "bar"}]})
self.assertEqual(
- self.get(url='/?%66%6F%6f=%62%61%72&')['status'],
- 200,
- 'match arguments hex',
- ) # FAIL
+ self.get(url='/?%66%6F%6f=%62%61%72&')['status'], 200, 'hex'
+ )
def test_routes_match_arguments_chars(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"arguments": {"foo": "-._()[],;"}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match arguments chars configure',
- )
+ self.route_match({"arguments": {"foo": "-._()[],;"}})
- self.assertEqual(
- self.get(url='/?foo=-._()[],;')['status'],
- 200,
- 'match arguments chars',
- )
+ self.assertEqual(self.get(url='/?foo=-._()[],;')['status'], 200, 'chs')
def test_routes_match_arguments_complex(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"arguments": {"foo": ""}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match arguments complex configure',
- )
+ self.route_match({"arguments": {"foo": ""}})
+ self.assertEqual(self.get(url='/?foo')['status'], 200, 'complex')
self.assertEqual(
- self.get(url='/?foo')['status'],
- 200,
- 'match arguments complex',
+ self.get(url='/?blah=blah&foo=')['status'], 200, 'complex 2'
)
self.assertEqual(
- self.get(url='/?blah=blah&foo=')['status'],
- 200,
- 'match arguments complex 2',
+ self.get(url='/?&&&foo&&&')['status'], 200, 'complex 3'
)
self.assertEqual(
- self.get(url='/?&&&foo&&&')['status'],
- 200,
- 'match arguments complex 3',
+ self.get(url='/?foo&foo=bar&foo')['status'], 404, 'complex 4'
)
self.assertEqual(
- self.get(url='/?foo&foo=bar&foo')['status'],
- 404,
- 'match arguments complex 4',
+ self.get(url='/?foo=&foo')['status'], 200, 'complex 5'
)
self.assertEqual(
- self.get(url='/?foo=&foo')['status'],
- 200,
- 'match arguments complex 5',
+ self.get(url='/?&=&foo&==&')['status'], 200, 'complex 6'
)
self.assertEqual(
- self.get(url='/?&=&foo&==&')['status'],
- 200,
- 'match arguments complex 6',
- )
- self.assertEqual(
- self.get(url='/?&=&bar&==&')['status'],
- 404,
- 'match arguments complex 7',
+ self.get(url='/?&=&bar&==&')['status'], 404, 'complex 7'
)
def test_routes_match_arguments_multiple(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"arguments": {"foo": "bar", "blah": "test"}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match arguments multiple configure',
- )
-
- self.assertEqual(self.get()['status'], 404, 'match arguments multiple')
+ self.route_match({"arguments": {"foo": "bar", "blah": "test"}})
+ self.assertEqual(self.get()['status'], 404, 'multiple')
self.assertEqual(
- self.get(url='/?foo=bar&blah=test')['status'],
- 200,
- 'match arguments multiple 2',
+ self.get(url='/?foo=bar&blah=test')['status'], 200, 'multiple 2'
)
-
self.assertEqual(
- self.get(url='/?foo=bar&blah')['status'],
- 404,
- 'match arguments multiple 3',
+ self.get(url='/?foo=bar&blah')['status'], 404, 'multiple 3'
)
def test_routes_match_arguments_multiple_rules(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"arguments": {"foo": ["bar", "blah"]}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match arguments multiple rules configure',
- )
-
- self.assertEqual(
- self.get()['status'], 404, 'match arguments multiple rules'
- )
-
- self.assertEqual(
- self.get(url='/?foo=bar')['status'],
- 200,
- 'match arguments multiple rules 2',
- )
-
- self.assertEqual(
- self.get(url='/?foo=blah')['status'],
- 200,
- 'match arguments multiple rules 3',
- )
+ self.route_match({"arguments": {"foo": ["bar", "blah"]}})
+ self.assertEqual(self.get()['status'], 404, 'rules')
+ self.assertEqual(self.get(url='/?foo=bar')['status'], 200, 'rules 2')
+ self.assertEqual(self.get(url='/?foo=blah')['status'], 200, 'rules 3')
self.assertEqual(
self.get(url='/?foo=blah&foo=bar&foo=blah')['status'],
200,
- 'match arguments multiple rules 4',
+ 'rules 4',
)
-
self.assertEqual(
- self.get(url='/?foo=blah&foo=bar&foo=')['status'],
- 404,
- 'match arguments multiple rules 5',
+ self.get(url='/?foo=blah&foo=bar&foo=')['status'], 404, 'rules 5'
)
def test_routes_match_arguments_array(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {
- "arguments": [
- {"var1": "val1*"},
- {"var2": "val2"},
- {"var3": ["foo", "bar"]},
- {"var1": "bar", "var4": "foo"},
- ]
- },
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match arguments array configure',
+ self.route_match(
+ {
+ "arguments": [
+ {"var1": "val1*"},
+ {"var2": "val2"},
+ {"var3": ["foo", "bar"]},
+ {"var1": "bar", "var4": "foo"},
+ ]
+ }
)
- self.assertEqual(self.get()['status'], 404, 'match arguments array')
+ self.assertEqual(self.get()['status'], 404, 'arr')
+ self.assertEqual(self.get(url='/?var1=val123')['status'], 200, 'arr 2')
+ self.assertEqual(self.get(url='/?var2=val2')['status'], 200, 'arr 3')
+ self.assertEqual(self.get(url='/?var3=bar')['status'], 200, 'arr 4')
+ self.assertEqual(self.get(url='/?var1=bar')['status'], 404, 'arr 5')
self.assertEqual(
- self.get(url='/?var1=val123')['status'],
- 200,
- 'match arguments array 2',
- )
- self.assertEqual(
- self.get(url='/?var2=val2')['status'],
- 200,
- 'match arguments array 3',
- )
- self.assertEqual(
- self.get(url='/?var3=bar')['status'],
- 200,
- 'match arguments array 4',
- )
- self.assertEqual(
- self.get(url='/?var1=bar')['status'],
- 404,
- 'match arguments array 5',
- )
- self.assertEqual(
- self.get(url='/?var1=bar&var4=foo')['status'],
- 200,
- 'match arguments array 6',
+ self.get(url='/?var1=bar&var4=foo')['status'], 200, 'arr 6'
)
self.assertIn(
@@ -2214,574 +1244,514 @@ class TestRouting(TestApplicationProto):
'match arguments array configure 2',
)
- self.assertEqual(
- self.get(url='/?var2=val2')['status'],
- 404,
- 'match arguments array 7',
- )
- self.assertEqual(
- self.get(url='/?var3=foo')['status'],
- 200,
- 'match arguments array 8',
- )
+ self.assertEqual(self.get(url='/?var2=val2')['status'], 404, 'arr 7')
+ self.assertEqual(self.get(url='/?var3=foo')['status'], 200, 'arr 8')
def test_routes_match_cookies(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"cookies": {"foO": "bar"}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match cookie configure',
- )
+ self.route_match({"cookies": {"foO": "bar"}})
+
+ self.assertEqual(self.get()['status'], 404, 'cookie')
+ self.cookie('foO=bar', 200)
+ self.cookie('foO=bar;1', 200)
+ self.cookie(['foO=bar', 'blah=blah'], 200)
+ self.cookie('foO=bar; blah=blah', 200)
+ self.cookie('Foo=bar', 404)
+ self.cookie('foO=Bar', 404)
+ self.cookie('foO=bar1', 404)
+ self.cookie('1foO=bar;', 404)
- self.assertEqual(self.get()['status'], 404, 'match cookie')
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'foO=bar',
- 'Connection': 'close',
- },
- )['status'],
- 200,
- 'match cookies 2',
- )
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': ['foO=bar', 'blah=blah'],
- 'Connection': 'close',
- },
- )['status'],
- 200,
- 'match cookies 3',
- )
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'foO=bar; blah=blah',
- 'Connection': 'close',
- },
- )['status'],
- 200,
- 'match cookies 4',
- )
+ def test_routes_match_cookies_empty(self):
+ self.route_match({"cookies": {}})
+ self.assertEqual(self.get()['status'], 200, 'cookies empty')
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'Foo=bar',
- 'Connection': 'close',
- },
- )['status'],
- 404,
- 'match cookies case sensitive',
- )
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'foO=Bar',
- 'Connection': 'close',
- },
- )['status'],
- 404,
- 'match cookies case sensitive 2',
- )
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'foO=bar1',
- 'Connection': 'close',
- },
- )['status'],
- 404,
- 'match cookies exact',
- )
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': '1foO=bar;',
- 'Connection': 'close',
- },
- )['status'],
- 404,
- 'match cookies exact 2',
- )
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'foO=bar;1',
- 'Connection': 'close',
- },
- )['status'],
- 200,
- 'match cookies exact 3',
- )
+ self.route_match({"cookies": []})
+ self.assertEqual(self.get()['status'], 200, 'cookies empty 2')
- def test_routes_match_cookies_empty(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"cookies": {}},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match cookies empty configure',
+ def test_routes_match_cookies_invalid(self):
+ self.route_match_invalid({"cookies": ["var"]})
+ self.route_match_invalid({"cookies": [{"foo": {}}]})
+
+ def test_routes_match_cookies_multiple(self):
+ self.route_match({"cookies": {"foo": "bar", "blah": "blah"}})
+
+ self.assertEqual(self.get()['status'], 404, 'multiple')
+ self.cookie('foo=bar; blah=blah', 200)
+ self.cookie(['foo=bar', 'blah=blah'], 200)
+ self.cookie(['foo=bar; blah', 'blah'], 404)
+ self.cookie(['foo=bar; blah=test', 'blah=blah'], 404)
+
+ def test_routes_match_cookies_multiple_values(self):
+ self.route_match({"cookies": {"blah": "blah"}})
+
+ self.cookie(['blah=blah', 'blah=blah', 'blah=blah'], 200)
+ self.cookie(['blah=blah', 'blah=test', 'blah=blah'], 404)
+ self.cookie(['blah=blah; blah=', 'blah=blah'], 404)
+
+ def test_routes_match_cookies_multiple_rules(self):
+ self.route_match({"cookies": {"blah": ["test", "blah"]}})
+
+ self.assertEqual(self.get()['status'], 404, 'multiple rules')
+ self.cookie('blah=test', 200)
+ self.cookie('blah=blah', 200)
+ self.cookie(['blah=blah', 'blah=test', 'blah=blah'], 200)
+ self.cookie(['blah=blah; blah=test', 'blah=blah'], 200)
+ self.cookie(['blah=blah', 'blah'], 200) # invalid cookie
+
+ def test_routes_match_cookies_array(self):
+ self.route_match(
+ {
+ "cookies": [
+ {"var1": "val1*"},
+ {"var2": "val2"},
+ {"var3": ["foo", "bar"]},
+ {"var1": "bar", "var4": "foo"},
+ ]
+ }
)
- self.assertEqual(self.get()['status'], 200, 'match cookies empty')
+ self.assertEqual(self.get()['status'], 404, 'cookies array')
+ self.cookie('var1=val123', 200)
+ self.cookie('var2=val2', 200)
+ self.cookie(' var2=val2 ', 200)
+ self.cookie('var3=bar', 200)
+ self.cookie('var3=bar;', 200)
+ self.cookie('var1=bar', 404)
+ self.cookie('var1=bar; var4=foo;', 200)
+ self.cookie(['var1=bar', 'var4=foo'], 200)
self.assertIn(
'success',
- self.route(
- {
- "match": {"cookies": []},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match cookies empty configure 2',
+ self.conf_delete('routes/0/match/cookies/1'),
+ 'match cookies array configure 2',
)
- self.assertEqual(self.get()['status'], 200, 'match cookies empty 2')
+ self.cookie('var2=val2', 404)
+ self.cookie('var3=foo', 200)
- def test_routes_match_cookies_invalid(self):
- self.assertIn(
- 'error',
- self.route(
- {
- "match": {"cookies": ["var"]},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match cookies invalid',
+ def test_routes_match_scheme(self):
+ self.route_match({"scheme": "http"})
+ self.route_match({"scheme": "https"})
+ self.route_match({"scheme": "HtTp"})
+ self.route_match({"scheme": "HtTpS"})
+
+ def test_routes_match_scheme_invalid(self):
+ self.route_match_invalid({"scheme": ["http"]})
+ self.route_match_invalid({"scheme": "ftp"})
+ self.route_match_invalid({"scheme": "ws"})
+ self.route_match_invalid({"scheme": "*"})
+ self.route_match_invalid({"scheme": ""})
+
+ def test_routes_source_port(self):
+ def sock_port():
+ _, sock = self.http(b'', start=True, raw=True, no_recv=True)
+ port = sock.getsockname()[1]
+ return (sock, port)
+
+ sock, port = sock_port()
+ sock2, port2 = sock_port()
+
+ self.route_match({"source": "127.0.0.1:" + str(port)})
+ self.assertEqual(self.get(sock=sock)['status'], 200, 'exact')
+ self.assertEqual(self.get(sock=sock2)['status'], 404, 'exact 2')
+
+ sock, port = sock_port()
+ sock2, port2 = sock_port()
+
+ self.route_match({"source": "!127.0.0.1:" + str(port)})
+ self.assertEqual(self.get(sock=sock)['status'], 404, 'negative')
+ self.assertEqual(self.get(sock=sock2)['status'], 200, 'negative 2')
+
+ sock, port = sock_port()
+ sock2, port2 = sock_port()
+
+ self.route_match(
+ {"source": "127.0.0.1:" + str(port) + "-" + str(port)}
+ )
+ self.assertEqual(self.get(sock=sock)['status'], 200, 'range single')
+ self.assertEqual(self.get(sock=sock2)['status'], 404, 'range single 2')
+
+ socks = [
+ sock_port(),
+ sock_port(),
+ sock_port(),
+ sock_port(),
+ sock_port(),
+ ]
+ socks.sort(key=lambda sock: sock[1])
+
+ self.route_match(
+ {
+ "source": "127.0.0.1:"
+ + str(socks[1][1]) # second port number
+ + "-"
+ + str(socks[3][1]) # fourth port number
+ }
)
+ self.assertEqual(self.get(sock=socks[0][0])['status'], 404, 'range')
+ self.assertEqual(self.get(sock=socks[1][0])['status'], 200, 'range 2')
+ self.assertEqual(self.get(sock=socks[2][0])['status'], 200, 'range 3')
+ self.assertEqual(self.get(sock=socks[3][0])['status'], 200, 'range 4')
+ self.assertEqual(self.get(sock=socks[4][0])['status'], 404, 'range 5')
- self.assertIn(
- 'error',
- self.route(
- {
- "match": {"cookies": [{"foo": {}}]},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match cookies invalid 2',
+ socks = [
+ sock_port(),
+ sock_port(),
+ sock_port(),
+ ]
+ socks.sort(key=lambda sock: sock[1])
+
+ self.route_match(
+ {
+ "source": [
+ "127.0.0.1:" + str(socks[0][1]),
+ "127.0.0.1:" + str(socks[2][1]),
+ ]
+ }
)
+ self.assertEqual(self.get(sock=socks[0][0])['status'], 200, 'array')
+ self.assertEqual(self.get(sock=socks[1][0])['status'], 404, 'array 2')
+ self.assertEqual(self.get(sock=socks[2][0])['status'], 200, 'array 3')
- def test_routes_match_cookies_multiple(self):
+ def test_routes_source_addr(self):
self.assertIn(
'success',
- self.route(
+ self.conf(
{
- "match": {"cookies": {"foo": "bar", "blah": "blah"}},
- "action": {"pass": "applications/empty"},
- }
+ "*:7080": {"pass": "routes"},
+ "[::1]:7081": {"pass": "routes"},
+ },
+ 'listeners',
),
- 'match cookies multiple configure',
+ 'source listeners configure',
)
- self.assertEqual(self.get()['status'], 404, 'match cookies multiple')
+ def get_ipv6():
+ return self.get(sock_type='ipv6', port=7081)
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'foo=bar; blah=blah',
- 'Connection': 'close',
- }
- )['status'],
- 200,
- 'match cookies multiple 2',
- )
+ self.route_match({"source": "127.0.0.1"})
+ self.assertEqual(self.get()['status'], 200, 'exact')
+ self.assertEqual(get_ipv6()['status'], 404, 'exact ipv6')
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': ['foo=bar', 'blah=blah'],
- 'Connection': 'close',
- }
- )['status'],
- 200,
- 'match cookies multiple 3',
- )
+ self.route_match({"source": ["127.0.0.1"]})
+ self.assertEqual(self.get()['status'], 200, 'exact 2')
+ self.assertEqual(get_ipv6()['status'], 404, 'exact 2 ipv6')
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': ['foo=bar; blah', 'blah'],
- 'Connection': 'close',
- }
- )['status'],
- 404,
- 'match cookies multiple 4',
- )
+ self.route_match({"source": "!127.0.0.1"})
+ self.assertEqual(self.get()['status'], 404, 'exact neg')
+ self.assertEqual(get_ipv6()['status'], 200, 'exact neg ipv6')
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': ['foo=bar; blah=test', 'blah=blah'],
- 'Connection': 'close',
- }
- )['status'],
- 404,
- 'match cookies multiple 5',
- )
+ self.route_match({"source": "127.0.0.2"})
+ self.assertEqual(self.get()['status'], 404, 'exact 3')
+ self.assertEqual(get_ipv6()['status'], 404, 'exact 3 ipv6')
- def test_routes_match_cookies_multiple_values(self):
+ self.route_match({"source": "127.0.0.1-127.0.0.1"})
+ self.assertEqual(self.get()['status'], 200, 'range single')
+ self.assertEqual(get_ipv6()['status'], 404, 'range single ipv6')
+
+ self.route_match({"source": "127.0.0.2-127.0.0.2"})
+ self.assertEqual(self.get()['status'], 404, 'range single 2')
+ self.assertEqual(get_ipv6()['status'], 404, 'range single 2 ipv6')
+
+ self.route_match({"source": "127.0.0.2-127.0.0.3"})
+ self.assertEqual(self.get()['status'], 404, 'range')
+ self.assertEqual(get_ipv6()['status'], 404, 'range ipv6')
+
+ self.route_match({"source": "127.0.0.1-127.0.0.2"})
+ self.assertEqual(self.get()['status'], 200, 'range 2')
+ self.assertEqual(get_ipv6()['status'], 404, 'range 2 ipv6')
+
+ self.route_match({"source": "127.0.0.0-127.0.0.2"})
+ self.assertEqual(self.get()['status'], 200, 'range 3')
+ self.assertEqual(get_ipv6()['status'], 404, 'range 3 ipv6')
+
+ self.route_match({"source": "127.0.0.0-127.0.0.1"})
+ self.assertEqual(self.get()['status'], 200, 'range 4')
+ self.assertEqual(get_ipv6()['status'], 404, 'range 4 ipv6')
+
+ self.route_match({"source": "126.0.0.0-127.0.0.0"})
+ self.assertEqual(self.get()['status'], 404, 'range 5')
+ self.assertEqual(get_ipv6()['status'], 404, 'range 5 ipv6')
+
+ self.route_match({"source": "126.126.126.126-127.0.0.2"})
+ self.assertEqual(self.get()['status'], 200, 'range 6')
+ self.assertEqual(get_ipv6()['status'], 404, 'range 6 ipv6')
+
+ def test_routes_source_ipv6(self):
self.assertIn(
'success',
- self.route(
+ self.conf(
{
- "match": {"cookies": {"blah": "blah"}},
- "action": {"pass": "applications/empty"},
- }
+ "[::1]:7080": {"pass": "routes"},
+ "127.0.0.1:7081": {"pass": "routes"},
+ },
+ 'listeners',
),
- 'match cookies multiple values configure',
+ 'source listeners configure',
)
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': ['blah=blah', 'blah=blah', 'blah=blah'],
- 'Connection': 'close',
- }
- )['status'],
- 200,
- 'match headers multiple values',
- )
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': ['blah=blah', 'blah=test', 'blah=blah'],
- 'Connection': 'close',
- }
- )['status'],
- 404,
- 'match cookies multiple values 2',
- )
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': ['blah=blah; blah=', 'blah=blah'],
- 'Connection': 'close',
- }
- )['status'],
- 404,
- 'match cookies multiple values 3',
- )
+ self.route_match({"source": "::1"})
+ self.assertEqual(self.get(sock_type='ipv6')['status'], 200, 'exact')
+ self.assertEqual(self.get(port=7081)['status'], 404, 'exact ipv4')
- def test_routes_match_cookies_multiple_rules(self):
+ self.route_match({"source": ["::1"]})
+ self.assertEqual(self.get(sock_type='ipv6')['status'], 200, 'exact 2')
+ self.assertEqual(self.get(port=7081)['status'], 404, 'exact 2 ipv4')
+
+ self.route_match({"source": "!::1"})
+ self.assertEqual(self.get(sock_type='ipv6')['status'], 404, 'exact neg')
+ self.assertEqual(self.get(port=7081)['status'], 200, 'exact neg ipv4')
+
+ self.route_match({"source": "::2"})
+ self.assertEqual(self.get(sock_type='ipv6')['status'], 404, 'exact 3')
+ self.assertEqual(self.get(port=7081)['status'], 404, 'exact 3 ipv4')
+
+ self.route_match({"source": "::1-::1"})
+ self.assertEqual(self.get(sock_type='ipv6')['status'], 200, 'range')
+ self.assertEqual(self.get(port=7081)['status'], 404, 'range ipv4')
+
+ self.route_match({"source": "::2-::2"})
+ self.assertEqual(self.get(sock_type='ipv6')['status'], 404, 'range 2')
+ self.assertEqual(self.get(port=7081)['status'], 404, 'range 2 ipv4')
+
+ self.route_match({"source": "::2-::3"})
+ self.assertEqual(self.get(sock_type='ipv6')['status'], 404, 'range 3')
+ self.assertEqual(self.get(port=7081)['status'], 404, 'range 3 ipv4')
+
+ self.route_match({"source": "::1-::2"})
+ self.assertEqual(self.get(sock_type='ipv6')['status'], 200, 'range 4')
+ self.assertEqual(self.get(port=7081)['status'], 404, 'range 4 ipv4')
+
+ self.route_match({"source": "::0-::2"})
+ self.assertEqual(self.get(sock_type='ipv6')['status'], 200, 'range 5')
+ self.assertEqual(self.get(port=7081)['status'], 404, 'range 5 ipv4')
+
+ self.route_match({"source": "::0-::1"})
+ self.assertEqual(self.get(sock_type='ipv6')['status'], 200, 'range 6')
+ self.assertEqual(self.get(port=7081)['status'], 404, 'range 6 ipv4')
+
+ def test_routes_source_cidr(self):
self.assertIn(
'success',
- self.route(
+ self.conf(
{
- "match": {"cookies": {"blah": ["test", "blah"]}},
- "action": {"pass": "applications/empty"},
- }
+ "*:7080": {"pass": "routes"},
+ "[::1]:7081": {"pass": "routes"},
+ },
+ 'listeners',
),
- 'match cookies multiple rules configure',
+ 'source listeners configure',
)
- self.assertEqual(
- self.get()['status'], 404, 'match cookies multiple rules'
- )
+ def get_ipv6():
+ return self.get(sock_type='ipv6', port=7081)
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'blah=test',
- 'Connection': 'close',
- }
- )['status'],
- 200,
- 'match cookies multiple rules 2',
- )
+ self.route_match({"source": "127.0.0.1/32"})
+ self.assertEqual(self.get()['status'], 200, '32')
+ self.assertEqual(get_ipv6()['status'], 404, '32 ipv6')
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'blah=blah',
- 'Connection': 'close',
- }
- )['status'],
- 200,
- 'match cookies multiple rules 3',
- )
+ self.route_match({"source": "127.0.0.0/32"})
+ self.assertEqual(self.get()['status'], 404, '32 2')
+ self.assertEqual(get_ipv6()['status'], 404, '32 2 ipv6')
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': ['blah=blah', 'blah=test', 'blah=blah'],
- 'Connection': 'close',
- }
- )['status'],
- 200,
- 'match cookies multiple rules 4',
- )
+ self.route_match({"source": "127.0.0.0/31"})
+ self.assertEqual(self.get()['status'], 200, '31')
+ self.assertEqual(get_ipv6()['status'], 404, '31 ipv6')
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': ['blah=blah; blah=test', 'blah=blah'],
- 'Connection': 'close',
- }
- )['status'],
- 200,
- 'match cookies multiple rules 5',
- )
+ self.route_match({"source": "0.0.0.0/1"})
+ self.assertEqual(self.get()['status'], 200, '1')
+ self.assertEqual(get_ipv6()['status'], 404, '1 ipv6')
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': ['blah=blah', 'blah'], # invalid cookie
- 'Connection': 'close',
- }
- )['status'],
- 200,
- 'match cookies multiple rules 6',
- )
+ self.route_match({"source": "0.0.0.0/0"})
+ self.assertEqual(self.get()['status'], 200, '0')
+ self.assertEqual(get_ipv6()['status'], 404, '0 ipv6')
- def test_routes_match_cookies_array(self):
+ def test_routes_source_cidr_ipv6(self):
self.assertIn(
'success',
- self.route(
+ self.conf(
{
- "match": {
- "cookies": [
- {"var1": "val1*"},
- {"var2": "val2"},
- {"var3": ["foo", "bar"]},
- {"var1": "bar", "var4": "foo"},
- ]
- },
- "action": {"pass": "applications/empty"},
- }
+ "[::1]:7080": {"pass": "routes"},
+ "127.0.0.1:7081": {"pass": "routes"},
+ },
+ 'listeners',
),
- 'match cookies array configure',
+ 'source listeners configure',
)
- self.assertEqual(self.get()['status'], 404, 'match cookies array')
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'var1=val123',
- 'Connection': 'close',
- },
- )['status'],
- 200,
- 'match cookies array 2',
- )
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'var2=val2',
- 'Connection': 'close',
- },
- )['status'],
- 200,
- 'match cookies array 3',
- )
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'var3=bar',
- 'Connection': 'close',
- },
- )['status'],
- 200,
- 'match cookies array 4',
- )
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'var3=bar;',
- 'Connection': 'close',
- },
- )['status'],
- 200,
- 'match cookies array 5',
- )
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'var1=bar',
- 'Connection': 'close',
- },
- )['status'],
- 404,
- 'match cookies array 6',
- )
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'var1=bar; var4=foo;',
- 'Connection': 'close',
- },
- )['status'],
- 200,
- 'match cookies array 7',
- )
- self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': ['var1=bar', 'var4=foo'],
- 'Connection': 'close',
- },
- )['status'],
- 200,
- 'match cookies array 8',
- )
+ self.route_match({"source": "::1/128"})
+ self.assertEqual(self.get(sock_type='ipv6')['status'], 200, '128')
+ self.assertEqual(self.get(port=7081)['status'], 404, '128 ipv4')
+
+ self.route_match({"source": "::0/128"})
+ self.assertEqual(self.get(sock_type='ipv6')['status'], 404, '128 2')
+ self.assertEqual(self.get(port=7081)['status'], 404, '128 ipv4')
+
+ self.route_match({"source": "::0/127"})
+ self.assertEqual(self.get(sock_type='ipv6')['status'], 200, '127')
+ self.assertEqual(self.get(port=7081)['status'], 404, '127 ipv4')
+
+ self.route_match({"source": "::0/32"})
+ self.assertEqual(self.get(sock_type='ipv6')['status'], 200, '32')
+ self.assertEqual(self.get(port=7081)['status'], 404, '32 ipv4')
+
+ self.route_match({"source": "::0/1"})
+ self.assertEqual(self.get(sock_type='ipv6')['status'], 200, '1')
+ self.assertEqual(self.get(port=7081)['status'], 404, '1 ipv4')
+
+ self.route_match({"source": "::/0"})
+ self.assertEqual(self.get(sock_type='ipv6')['status'], 200, '0')
+ self.assertEqual(self.get(port=7081)['status'], 404, '0 ipv4')
+
+ def test_routes_source_unix(self):
+ addr = self.testdir + '/sock'
self.assertIn(
'success',
- self.conf_delete('routes/0/match/cookies/1'),
- 'match cookies array configure 2',
+ self.conf({"unix:" + addr: {"pass": "routes"}}, 'listeners'),
+ 'source listeners configure',
)
+ self.route_match({"source": "!0.0.0.0/0"})
self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'var2=val2',
- 'Connection': 'close',
- },
- )['status'],
- 404,
- 'match cookies array 9',
+ self.get(sock_type='unix', addr=addr)['status'], 200, 'unix ipv4'
)
+
+ self.route_match({"source": "!::/0"})
self.assertEqual(
- self.get(
- headers={
- 'Host': 'localhost',
- 'Cookie': 'var3=foo',
- 'Connection': 'close',
- },
- )['status'],
- 200,
- 'match cookies array 10',
+ self.get(sock_type='unix', addr=addr)['status'], 200, 'unix ipv6'
)
- def test_routes_match_scheme(self):
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"scheme": "http"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match scheme http configure',
- )
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"scheme": "https"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match scheme https configure',
+ def test_routes_match_source(self):
+ self.route_match({"source": "::"})
+ self.route_match(
+ {
+ "source": [
+ "127.0.0.1",
+ "192.168.0.10:8080",
+ "192.168.0.11:8080-8090",
+ ]
+ }
)
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"scheme": "HtTp"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match scheme http case insensitive configure',
+ self.route_match(
+ {
+ "source": [
+ "10.0.0.0/8",
+ "10.0.0.0/7:1000",
+ "10.0.0.0/32:8080-8090",
+ ]
+ }
)
- self.assertIn(
- 'success',
- self.route(
- {
- "match": {"scheme": "HtTpS"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'match scheme https case insensitive configure',
+ self.route_match(
+ {
+ "source": [
+ "10.0.0.0-10.0.0.1",
+ "10.0.0.0-11.0.0.0:1000",
+ "127.0.0.0-127.0.0.255:8080-8090",
+ ]
+ }
)
-
- def test_routes_match_scheme_invalid(self):
- self.assertIn(
- 'error',
- self.route(
- {
- "match": {"scheme": ["http"]},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'scheme invalid type no arrays allowed',
+ self.route_match(
+ {"source": ["2001::", "[2002::]:8000", "[2003::]:8080-8090"]}
)
- self.assertIn(
- 'error',
- self.route(
- {
- "match": {"scheme": "ftp"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'scheme invalid protocol 1',
+ self.route_match(
+ {
+ "source": [
+ "2001::-200f:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
+ "[fe08::-feff::]:8000",
+ "[fff0::-fff0::10]:8080-8090",
+ ]
+ }
)
- self.assertIn(
- 'error',
- self.route(
- {
- "match": {"scheme": "ws"},
- "action": {"pass": "applications/empty"},
- }
- ),
- 'scheme invalid protocol 2',
+ self.route_match(
+ {
+ "source": [
+ "2001::/16",
+ "[0ff::/64]:8000",
+ "[fff0:abcd:ffff:ffff:ffff::/128]:8080-8090",
+ ]
+ }
)
+ self.route_match({"source": "*:0-65535"})
+ self.assertEqual(self.get()['status'], 200, 'source any')
+
+ def test_routes_match_source_invalid(self):
+ self.route_match_invalid({"source": "127"})
+ self.route_match_invalid({"source": "256.0.0.1"})
+ self.route_match_invalid({"source": "127.0.0."})
+ self.route_match_invalid({"source": "127.0.0.1:"})
+ self.route_match_invalid({"source": "127.0.0.1/"})
+ self.route_match_invalid({"source": "11.0.0.0/33"})
+ self.route_match_invalid({"source": "11.0.0.0/65536"})
+ self.route_match_invalid({"source": "11.0.0.0-10.0.0.0"})
+ self.route_match_invalid({"source": "11.0.0.0:3000-2000"})
+ self.route_match_invalid({"source": ["11.0.0.0:3000-2000"]})
+ self.route_match_invalid({"source": "[2001::]:3000-2000"})
+ self.route_match_invalid({"source": "2001::-2000::"})
+ self.route_match_invalid({"source": "2001::/129"})
+ self.route_match_invalid({"source": "::FFFFF"})
+ self.route_match_invalid({"source": "[::1]:"})
+ self.route_match_invalid({"source": "*:"})
+ self.route_match_invalid({"source": "*:1-a"})
+ self.route_match_invalid({"source": "*:65536"})
+
+ def test_routes_match_destination(self):
self.assertIn(
- 'error',
- self.route(
- {
- "match": {"scheme": "*"},
- "action": {"pass": "applications/empty"},
- }
+ 'success',
+ self.conf(
+ {"*:7080": {"pass": "routes"}, "*:7081": {"pass": "routes"}},
+ 'listeners',
),
- 'scheme invalid no wildcard allowed',
+ 'listeners configure',
)
+
+ self.route_match({"destination": "*:7080"})
+ self.assertEqual(self.get()['status'], 200, 'dest')
+ self.assertEqual(self.get(port=7081)['status'], 404, 'dest 2')
+
+ self.route_match({"destination": ["127.0.0.1:7080"]})
+ self.assertEqual(self.get()['status'], 200, 'dest 3')
+ self.assertEqual(self.get(port=7081)['status'], 404, 'dest 4')
+
+ self.route_match({"destination": "!*:7080"})
+ self.assertEqual(self.get()['status'], 404, 'dest neg')
+ self.assertEqual(self.get(port=7081)['status'], 200, 'dest neg 2')
+
+ def test_routes_match_destination_proxy(self):
self.assertIn(
- 'error',
- self.route(
+ 'success',
+ self.conf(
{
- "match": {"scheme": ""},
- "action": {"pass": "applications/empty"},
+ "listeners": {
+ "*:7080": {"pass": "routes/first"},
+ "*:7081": {"pass": "routes/second"},
+ },
+ "routes": {
+ "first": [
+ {"action": {"proxy": "http://127.0.0.1:7081"}}
+ ],
+ "second": [
+ {
+ "match": {"destination": ["127.0.0.1:7081"]},
+ "action": {"pass": "applications/empty"},
+ }
+ ],
+ },
+ "applications": {
+ "empty": {
+ "type": "python",
+ "processes": {"spare": 0},
+ "path": self.current_dir + "/python/empty",
+ "working_directory": self.current_dir
+ + "/python/empty",
+ "module": "wsgi",
+ }
+ },
}
),
- 'scheme invalid empty',
+ 'proxy configure',
)
+ self.assertEqual(self.get()['status'], 200, 'proxy')
+
if __name__ == '__main__':
TestRouting.main()
diff --git a/test/test_routing_tls.py b/test/test_routing_tls.py
index 3df2bc82..c6648095 100644
--- a/test/test_routing_tls.py
+++ b/test/test_routing_tls.py
@@ -48,10 +48,8 @@ class TestRoutingTLS(TestApplicationTLS):
'scheme configure',
)
- self.assertEqual(self.get()['status'], 200, 'scheme http')
- self.assertEqual(
- self.get_ssl(port=7081)['status'], 204, 'scheme https'
- )
+ self.assertEqual(self.get()['status'], 200, 'http')
+ self.assertEqual(self.get_ssl(port=7081)['status'], 204, 'https')
if __name__ == '__main__':
diff --git a/test/test_ruby_application.py b/test/test_ruby_application.py
index bbb252d7..83a71f96 100644
--- a/test/test_ruby_application.py
+++ b/test/test_ruby_application.py
@@ -285,7 +285,7 @@ class TestRubyApplication(TestApplicationRuby):
def test_ruby_application_body_empty(self):
self.load('body_empty')
- self.assertEqual(self.get()['body'], '0\r\n\r\n', 'body empty')
+ self.assertEqual(self.get()['body'], '', 'body empty')
def test_ruby_application_body_array(self):
self.load('body_array')
diff --git a/test/unit/applications/lang/go.py b/test/unit/applications/lang/go.py
index 18345828..7212a95c 100644
--- a/test/unit/applications/lang/go.py
+++ b/test/unit/applications/lang/go.py
@@ -23,7 +23,7 @@ class TestApplicationGo(TestApplicationProto):
os.mkdir(self.testdir + '/go')
env = os.environ.copy()
- env['GOPATH'] = self.pardir + '/go'
+ env['GOPATH'] = self.pardir + '/build/go'
try:
process = Popen(
@@ -44,7 +44,7 @@ class TestApplicationGo(TestApplicationProto):
return process
- def load(self, script, name='app'):
+ def load(self, script, name='app', **kwargs):
self.prepare_env(script, name)
self._load_conf(
@@ -60,5 +60,6 @@ class TestApplicationGo(TestApplicationProto):
"executable": self.testdir + "/go/" + name,
}
},
- }
+ },
+ **kwargs
)
diff --git a/test/unit/applications/lang/java.py b/test/unit/applications/lang/java.py
index bcf87f59..a370d96b 100644
--- a/test/unit/applications/lang/java.py
+++ b/test/unit/applications/lang/java.py
@@ -6,7 +6,7 @@ from unit.applications.proto import TestApplicationProto
class TestApplicationJava(TestApplicationProto):
- def load(self, script, name='app'):
+ def load(self, script, name='app', **kwargs):
app_path = self.testdir + '/java'
web_inf_path = app_path + '/WEB-INF/'
classes_path = web_inf_path + 'classes/'
@@ -82,5 +82,6 @@ class TestApplicationJava(TestApplicationProto):
"webapp": app_path,
}
},
- }
+ },
+ **kwargs
)
diff --git a/test/unit/applications/lang/node.py b/test/unit/applications/lang/node.py
index 3cc72669..d818298f 100644
--- a/test/unit/applications/lang/node.py
+++ b/test/unit/applications/lang/node.py
@@ -15,20 +15,22 @@ class TestApplicationNode(TestApplicationProto):
return unit if not complete_check else unit.complete()
- def load(self, script, name='app.js'):
+ def load(self, script, name='app.js', **kwargs):
# copy application
shutil.copytree(
self.current_dir + '/node/' + script, self.testdir + '/node'
)
- # link modules
+ # copy modules
- os.symlink(
+ shutil.copytree(
self.pardir + '/node/node_modules',
self.testdir + '/node/node_modules',
)
+ self.public_dir(self.testdir + '/node')
+
self._load_conf(
{
"listeners": {"*:7080": {"pass": "applications/" + script}},
@@ -40,5 +42,6 @@ class TestApplicationNode(TestApplicationProto):
"executable": name,
}
},
- }
+ },
+ **kwargs
)
diff --git a/test/unit/applications/lang/perl.py b/test/unit/applications/lang/perl.py
index 79df2cfa..d32aca33 100644
--- a/test/unit/applications/lang/perl.py
+++ b/test/unit/applications/lang/perl.py
@@ -4,7 +4,7 @@ from unit.applications.proto import TestApplicationProto
class TestApplicationPerl(TestApplicationProto):
application_type = "perl"
- def load(self, script, name='psgi.pl'):
+ def load(self, script, name='psgi.pl', **kwargs):
script_path = self.current_dir + '/perl/' + script
self._load_conf(
@@ -18,5 +18,6 @@ class TestApplicationPerl(TestApplicationProto):
"script": script_path + '/' + name,
}
},
- }
+ },
+ **kwargs
)
diff --git a/test/unit/applications/lang/php.py b/test/unit/applications/lang/php.py
index 9c54368d..6b1677e6 100644
--- a/test/unit/applications/lang/php.py
+++ b/test/unit/applications/lang/php.py
@@ -4,7 +4,7 @@ from unit.applications.proto import TestApplicationProto
class TestApplicationPHP(TestApplicationProto):
application_type = "php"
- def load(self, script, name='index.php'):
+ def load(self, script, name='index.php', **kwargs):
script_path = self.current_dir + '/php/' + script
self._load_conf(
@@ -19,5 +19,6 @@ class TestApplicationPHP(TestApplicationProto):
"index": name,
}
},
- }
+ },
+ **kwargs
)
diff --git a/test/unit/applications/lang/python.py b/test/unit/applications/lang/python.py
index ded76cb6..fdda024a 100644
--- a/test/unit/applications/lang/python.py
+++ b/test/unit/applications/lang/python.py
@@ -4,7 +4,7 @@ from unit.applications.proto import TestApplicationProto
class TestApplicationPython(TestApplicationProto):
application_type = "python"
- def load(self, script, name=None):
+ def load(self, script, name=None, **kwargs):
if name is None:
name = script
@@ -22,5 +22,6 @@ class TestApplicationPython(TestApplicationProto):
"module": "wsgi",
}
},
- }
+ },
+ **kwargs
)
diff --git a/test/unit/applications/lang/ruby.py b/test/unit/applications/lang/ruby.py
index d30735ad..8c8acecc 100644
--- a/test/unit/applications/lang/ruby.py
+++ b/test/unit/applications/lang/ruby.py
@@ -4,7 +4,7 @@ from unit.applications.proto import TestApplicationProto
class TestApplicationRuby(TestApplicationProto):
application_type = "ruby"
- def load(self, script, name='config.ru'):
+ def load(self, script, name='config.ru', **kwargs):
script_path = self.current_dir + '/ruby/' + script
self._load_conf(
@@ -18,5 +18,6 @@ class TestApplicationRuby(TestApplicationProto):
"script": script_path + '/' + name,
}
},
- }
+ },
+ **kwargs
)
diff --git a/test/unit/applications/proto.py b/test/unit/applications/proto.py
index 4105473f..ae1af354 100644
--- a/test/unit/applications/proto.py
+++ b/test/unit/applications/proto.py
@@ -25,7 +25,19 @@ class TestApplicationProto(TestControl):
return found
- def _load_conf(self, conf):
+ def _load_conf(self, conf, **kwargs):
+ if 'applications' in conf:
+ for app in conf['applications'].keys():
+ app_conf = conf['applications'][app]
+ if 'user' in kwargs:
+ app_conf['user'] = kwargs['user']
+
+ if 'group' in kwargs:
+ app_conf['group'] = kwargs['group']
+
+ if 'isolation' in kwargs:
+ app_conf['isolation'] = kwargs['isolation']
+
self.assertIn(
'success', self.conf(conf), 'load application configuration'
)
diff --git a/test/unit/feature/isolation.py b/test/unit/feature/isolation.py
index 9b06ab3c..3f474993 100644
--- a/test/unit/feature/isolation.py
+++ b/test/unit/feature/isolation.py
@@ -82,6 +82,3 @@ class TestFeatureIsolation(TestApplicationProto):
data = int(os.readlink(nspath)[len(nstype) + 2 : -1])
return data
-
- def parsejson(self, data):
- return json.loads(data.split('\n')[1])
diff --git a/test/unit/http.py b/test/unit/http.py
index c7e3e36d..839e91a2 100644
--- a/test/unit/http.py
+++ b/test/unit/http.py
@@ -1,5 +1,6 @@
import re
import time
+import json
import socket
import select
from unit.main import TestUnit
@@ -86,23 +87,24 @@ class TestHTTP(TestUnit):
sock.sendall(req)
+ encoding = 'utf-8' if 'encoding' not in kwargs else kwargs['encoding']
+
if TestUnit.detailed:
print('>>>')
try:
- print(req.decode('utf-8', 'ignore'))
+ print(req.decode(encoding, 'ignore'))
except UnicodeEncodeError:
print(req)
resp = ''
if 'no_recv' not in kwargs:
- enc = 'utf-8' if 'encoding' not in kwargs else kwargs['encoding']
read_timeout = (
30 if 'read_timeout' not in kwargs else kwargs['read_timeout']
)
resp = self.recvall(
sock, read_timeout=read_timeout, buff_size=read_buffer_size
- ).decode(enc)
+ ).decode(encoding)
if TestUnit.detailed:
print('<<<')
@@ -114,6 +116,15 @@ class TestHTTP(TestUnit):
if 'raw_resp' not in kwargs:
resp = self._resp_to_dict(resp)
+ headers = resp.get('headers')
+ if headers and headers.get('Transfer-Encoding') == 'chunked':
+ resp['body'] = self._parse_chunked_body(resp['body']).decode(
+ encoding
+ )
+
+ if 'json' in kwargs:
+ resp = self._parse_json(resp)
+
if 'start' not in kwargs:
sock.close()
return resp
@@ -151,7 +162,7 @@ class TestHTTP(TestUnit):
return data
def _resp_to_dict(self, resp):
- m = re.search('(.*?\x0d\x0a?)\x0d\x0a?(.*)', resp, re.M | re.S)
+ m = re.search(r'(.*?\x0d\x0a?)\x0d\x0a?(.*)', resp, re.M | re.S)
if not m:
return {}
@@ -162,12 +173,12 @@ class TestHTTP(TestUnit):
headers_lines = p.findall(headers_text)
status = re.search(
- '^HTTP\/\d\.\d\s(\d+)|$', headers_lines.pop(0)
+ r'^HTTP\/\d\.\d\s(\d+)|$', headers_lines.pop(0)
).group(1)
headers = {}
for line in headers_lines:
- m = re.search('(.*)\:\s(.*)', line)
+ m = re.search(r'(.*)\:\s(.*)', line)
if m.group(1) not in headers:
headers[m.group(1)] = m.group(2)
@@ -180,6 +191,65 @@ class TestHTTP(TestUnit):
return {'status': int(status), 'headers': headers, 'body': body}
+ def _parse_chunked_body(self, raw_body):
+ if isinstance(raw_body, str):
+ raw_body = bytes(raw_body.encode())
+
+ crlf = b'\r\n'
+ chunks = raw_body.split(crlf)
+
+ if len(chunks) < 3:
+ self.fail('Invalid chunked body')
+
+ if chunks.pop() != b'':
+ self.fail('No CRLF at the end of the body')
+
+ try:
+ last_size = int(chunks[-2], 16)
+ except:
+ self.fail('Invalid zero size chunk')
+
+ if last_size != 0 or chunks[-1] != b'':
+ self.fail('Incomplete body')
+
+ body = b''
+ while len(chunks) >= 2:
+ try:
+ size = int(chunks.pop(0), 16)
+ except:
+ self.fail('Invalid chunk size %s' % str(size))
+
+ if size == 0:
+ self.assertEqual(len(chunks), 1, 'last zero size')
+ break
+
+ temp_body = crlf.join(chunks)
+
+ body += temp_body[:size]
+
+ temp_body = temp_body[size + len(crlf) :]
+
+ chunks = temp_body.split(crlf)
+
+ return body
+
+ def _parse_json(self, resp):
+ headers = resp['headers']
+
+ self.assertIn('Content-Type', headers, 'Content-Type header set')
+ self.assertEqual(
+ headers['Content-Type'],
+ 'application/json',
+ 'Content-Type header is application/json',
+ )
+
+ resp['body'] = json.loads(resp['body'])
+
+ return resp
+
+ def getjson(self, **kwargs):
+ return self.get(json=True, **kwargs)
+
def waitforsocket(self, port):
ret = False
diff --git a/test/unit/main.py b/test/unit/main.py
index 094fdb0e..ea6afd7f 100644
--- a/test/unit/main.py
+++ b/test/unit/main.py
@@ -1,6 +1,7 @@
import os
import re
import sys
+import stat
import time
import fcntl
import shutil
@@ -20,6 +21,9 @@ class TestUnit(unittest.TestCase):
pardir = os.path.abspath(
os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)
)
+ is_su = os.geteuid() == 0
+ uid = os.geteuid()
+ gid = os.getegid()
architecture = platform.architecture()[0]
system = platform.system()
maxDiff = None
@@ -188,13 +192,19 @@ class TestUnit(unittest.TestCase):
self.stop_processes()
def _run(self):
- self.unitd = self.pardir + '/build/unitd'
+ build_dir = self.pardir + '/build'
+ self.unitd = build_dir + '/unitd'
if not os.path.isfile(self.unitd):
exit("Could not find unit")
self.testdir = tempfile.mkdtemp(prefix='unit-test-')
+ self.public_dir(self.testdir)
+
+ if oct(stat.S_IMODE(os.stat(build_dir).st_mode)) != '0o777':
+ self.public_dir(build_dir)
+
os.mkdir(self.testdir + '/state')
print()
@@ -328,6 +338,15 @@ class TestUnit(unittest.TestCase):
return ret
+ def public_dir(self, path):
+ os.chmod(path, 0o777)
+
+ for root, dirs, files in os.walk(path):
+ for d in dirs:
+ os.chmod(os.path.join(root, d), 0o777)
+ for f in files:
+ os.chmod(os.path.join(root, f), 0o777)
+
@staticmethod
def _parse_args():
parser = argparse.ArgumentParser(add_help=False)