Skip to content
Snippets Groups Projects
Commit 6d53c50e authored by slobinger's avatar slobinger
Browse files

Merge branch '20-enable-api-proxy-rootpath' into 'master'

Resolve "Basis-Pfad (/) bei API über Proxy nicht aufrufbar"

Closes #20

See merge request !15
parents eadcf56c 46dc81c6
Branches
Tags
1 merge request!15Resolve "Basis-Pfad (/) bei API über Proxy nicht aufrufbar"
Pipeline #
python3-sams-classes (1.0.1~1) UNRELEASED; urgency=medium
* fixed issue #20 "Basis-Pfad (/) bei API über Proxy nicht aufrufbar"
-- Lobinger <slobinger@justus.zib.de> Tue, 13 Jun 2017 15:28:43 +0200
python3-sams-classes (1.0.0) unstable; urgency=medium
* Initial Release.
-- Sebastian Lobinger <sebastian.lobinger@zib.de> Thu, 08 Jun 2017 10:42:38 +0200
\ No newline at end of file
......@@ -46,14 +46,18 @@ class SAMSApp:
endpoint = '_'.join(view['function'].split('.'))
view_func = SAMSApp._get_attr(self.module, view['function'])
self.__blueprint.add_url_rule(
rule = self._generate_url(view.get('url')), endpoint = endpoint,
rule = self._generate_url(urlPart = view.get('url')), endpoint = endpoint,
view_func = view_func)
def __add_proxy_urls(self):
i = 0
for proxy in self.proxies:
self.__blueprint.add_url_rule(
rule = self._generate_url(proxy.urlRule),
rule = self._generate_url(urlPart = proxy.urlRule),
endpoint = self.__blueprint.name.replace('.', '_') + '_proxy_' + str(i),
view_func = proxy.proxy)
self.__blueprint.add_url_rule(
rule = self._generate_url(urlPart = proxy.rootUrlRule),
endpoint = self.__blueprint.name.replace('.', '_') + '_proxy_' + str(i),
view_func = proxy.proxy)
i += 1
......@@ -107,15 +111,12 @@ class SAMSApp:
return entries
def _generate_url(
self, urlPrefix: str, urlPart: str = '', external = False ) -> str:
self, urlPrefix: str = '', urlPart: str = '', external = False ) -> str:
if external:
return urlPart
urlPrefix = urlPrefix.strip('/')
urlPart = urlPart.strip('/')
urlElements = []
if urlPrefix:
urlElements.append(urlPrefix)
if urlPart:
urlElements.append(urlPart)
url = '/'.join(urlElements)
return '/' + url if (not url) or (url[0] is not '/') else url
\ No newline at end of file
urlPart = urlPart.lstrip('/')
url = '/'.join([urlPrefix, urlPart])
if url[0] != '/':
url = '/' + url
return url
\ No newline at end of file
......@@ -22,8 +22,16 @@ class SAMSProxy:
if 0 == len(self._proxySpec['in']):
return '/<path:path>'
return '/' + urlRule + '/<path:path>'
@property
def rootUrlRule(self):
urlRule = self._proxySpec['in'].strip()
urlRule = urlRule.strip('/')
if 0 == len(self._proxySpec['in']):
return '/'
return '/' + urlRule + '/'
def proxy(self, path):
def proxy(self, path = ''):
url = '/'.join([self._proxySpec['out'].strip().rstrip('/'), path])
headers = SAMSProxy.__cleaned_dict(request.headers)
headers.pop('Content-Type', None)
......
......@@ -21,4 +21,9 @@ def passthrough():
body = request.get_json()
output = json.dumps(
{'url': request.args, 'body': body, 'header': dict(request.headers)})
return output
\ No newline at end of file
return output
@app.route('/', methods = [
'GET', 'POST', 'DELETE', 'UPDATE', 'PATCH', 'OPTIONS', 'PUT', 'HEAD'])
def rootpath():
return 'rootpath'
\ No newline at end of file
......@@ -153,7 +153,7 @@ class TestSAMSApp(unittest.TestCase):
app = SAMSApp(name = 'test', manifest = manifest
, langDict = {'en': langDict})
menu = app.menu(langCode = 'en', urlPrefix = '/test')
self.assertEqual(menu[0]['url'], '/test')
self.assertEqual(menu[0]['url'], '/test/')
self.assertEqual(menu[1]['url'], '/test/1')
def test_app_menu_external_urls(self):
......@@ -168,7 +168,7 @@ class TestSAMSApp(unittest.TestCase):
app = SAMSApp(name = 'test', manifest = manifest
, langDict = {'en': langDict})
menu = app.menu(langCode = 'en', urlPrefix = '/test')
self.assertEqual(menu[0]['url'], '/test')
self.assertEqual(menu[0]['url'], '/test/')
self.assertEqual(menu[1]['url'], 'http://zib.de')
def test_app_proxies_list(self):
......@@ -218,10 +218,11 @@ class TestSAMSAppWithThreadedApi(unittest.TestCase):
)
self.flaskApp.register_blueprint(testApp.blueprint)
self.assertGreater(len(list(self.flaskApp.url_map.iter_rules())), 1)
eprint(self.flaskApp.url_map)
with self.flaskApp.test_client(self) as client:
response = client.get('/api/hello')
self.assertIs(response.status_code, 200)
for path in ('/api/hello', '/api/'):
with self.subTest(path):
with self.flaskApp.test_client(self) as client:
response = client.get(path)
self.assertIs(response.status_code, 200)
if __name__ == '__main__':
unittest.main()
\ No newline at end of file
......@@ -68,6 +68,9 @@ class TestSAMSHubWithThreadedAPI(unittest.TestCase):
time.sleep(0.01)
self.proxyApp = Flask('test')
self.proxyApp.config['TESTING'] = True
self.basic_url_rule_params = {'endpoint': 'proxy',
'methods': ['GET', 'POST', 'PUT', 'UPDATE', 'PATCH', 'DELETE', 'OPTIONS']}
self.url_rule_properties = ['rootUrlRule', 'urlRule']
def tearDown(self):
response = requests.get('http://localhost:4711/shutdown')
......@@ -78,9 +81,9 @@ class TestSAMSHubWithThreadedAPI(unittest.TestCase):
"""The proxy passes json data """
proxy = SAMSProxy(
proxySpec = {'in': '/proxy', 'out': 'http://localhost:4711'})
self.proxyApp.add_url_rule(rule = proxy.urlRule, endpoint = 'proxy',
view_func = proxy.proxy, methods=['GET', 'POST', 'PUT', 'UPDATE',
'PATCH', 'DELETE', 'OPTIONS'])
for urlRuleProp in self.url_rule_properties:
self.proxyApp.add_url_rule(rule = getattr(proxy, urlRuleProp),
view_func = proxy.proxy, **self.basic_url_rule_params)
thProxyApp = FlaskInThread(self.proxyApp, host="localhost", port=5000)
thProxyApp.start()
time.sleep(0.01)
......@@ -99,9 +102,9 @@ class TestSAMSHubWithThreadedAPI(unittest.TestCase):
'user': {'name': 'u','param-type': 'url'},
'group': {'name': 'g', 'param-type': 'body'},
'language': {'name': 'Lang', 'param-type': 'header'}}}})
self.proxyApp.add_url_rule(rule = proxy.urlRule, endpoint = 'proxy',
view_func = proxy.proxy, methods=['GET', 'POST', 'PUT', 'UPDATE',
'PATCH', 'DELETE', 'OPTIONS'])
for urlRuleProp in self.url_rule_properties:
self.proxyApp.add_url_rule(rule = getattr(proxy, urlRuleProp),
view_func = proxy.proxy, **self.basic_url_rule_params)
self.proxyApp.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
with self.proxyApp.test_client(self) as client:
with client.session_transaction() as sess:
......@@ -125,9 +128,9 @@ class TestSAMSHubWithThreadedAPI(unittest.TestCase):
'user': {'name': 'u','param-type': 'url'},
'group': {'name': 'g', 'param-type': 'body'},
'language': {'name': 'lang', 'param-type': 'header'}}}})
self.proxyApp.add_url_rule(rule = proxy.urlRule, endpoint = 'proxy',
view_func = proxy.proxy, methods=['GET', 'POST', 'PUT', 'UPDATE',
'PATCH', 'DELETE', 'OPTIONS'])
for urlRuleProp in self.url_rule_properties:
self.proxyApp.add_url_rule(rule = getattr(proxy, urlRuleProp),
view_func = proxy.proxy, **self.basic_url_rule_params)
self.proxyApp.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
with self.proxyApp.test_client(self) as client:
with client.session_transaction() as sess:
......@@ -152,9 +155,9 @@ class TestSAMSHubWithThreadedAPI(unittest.TestCase):
'user': {'name': 'u','param-type': 'url'},
'group': {'name': 'g', 'param-type': 'body'},
'language': {'name': 'lang', 'param-type': 'header'}}}})
self.proxyApp.add_url_rule(rule = proxy.urlRule, endpoint = 'proxy',
view_func = proxy.proxy, methods=['GET', 'POST', 'PUT', 'UPDATE',
'PATCH', 'DELETE', 'OPTIONS'])
for urlRuleProp in self.url_rule_properties:
self.proxyApp.add_url_rule(rule = getattr(proxy, urlRuleProp),
view_func = proxy.proxy, **self.basic_url_rule_params)
self.proxyApp.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
with self.proxyApp.test_client(self) as client:
with client.session_transaction() as sess:
......@@ -171,23 +174,25 @@ class TestSAMSHubWithThreadedAPI(unittest.TestCase):
""" The proxy forwards a request to test flaskapp and returns 'hello' """
proxy = SAMSProxy(
proxySpec = {'in': '/proxy', 'out': 'http://localhost:4711'})
self.proxyApp.add_url_rule(rule = proxy.urlRule, endpoint = 'proxy',
view_func = proxy.proxy, methods=['GET', 'POST', 'PUT', 'UPDATE',
'PATCH', 'DELETE', 'OPTIONS'])
for urlRuleProp in self.url_rule_properties:
self.proxyApp.add_url_rule(rule = getattr(proxy, urlRuleProp),
view_func = proxy.proxy, **self.basic_url_rule_params)
with self.proxyApp.test_client(self) as client:
eprint(self.proxyApp.url_map)
for method in ['get', 'post', 'put', 'update', 'patch', 'delete',
'options']:
response = client.open(path='/proxy/hello', method=method.upper())
self.assertIs(response.status_code, 200, method)
self.assertEqual(response.data.decode('utf-8'), method + ' hello')
for path in ('/proxy/hello', '/proxy/'):
response = client.open(path = path, method = method.upper())
with self.subTest('method ' + method + ' path ' + path):
self.assertIs(response.status_code, 200, method)
def test_param_passthrough(self):
"""The proxy passes headers, form / data and url params """
proxy = SAMSProxy(
proxySpec = {'in': '/proxy', 'out': 'http://localhost:4711'})
self.proxyApp.add_url_rule(rule = proxy.urlRule, endpoint = 'proxy',
view_func = proxy.proxy, methods=['GET', 'POST', 'PUT', 'UPDATE',
'PATCH', 'DELETE', 'OPTIONS'])
for urlRuleProp in self.url_rule_properties:
self.proxyApp.add_url_rule(rule = getattr(proxy, urlRuleProp),
view_func = proxy.proxy, **self.basic_url_rule_params)
with self.proxyApp.test_client(self) as client:
res = client.get(path='/proxy/passthrough',
query_string={'u':'foo'}, data={'g':'bar'}, headers={'lang': 'klingon'})
......@@ -214,6 +219,9 @@ class TestSAMSHubWithThreadedAPI(unittest.TestCase):
proxyApp.add_url_rule(rule = proxy.urlRule, endpoint = 'proxy',
view_func = proxy.proxy, methods=['GET', 'POST', 'PUT', 'UPDATE',
'PATCH', 'DELETE', 'OPTIONS'])
proxyApp.add_url_rule(rule = proxy.rootUrlRule, endpoint = 'proxy',
view_func = proxy.proxy, methods=['GET', 'POST', 'PUT', 'UPDATE',
'PATCH', 'DELETE', 'OPTIONS'])
with proxyApp.test_client(self) as client:
res = client.get(path='/proxy/passthrough',
query_string={'u':'foo'}, data={'g':'bar'},
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment