Generate correct url in api pagination
Use protocol from X-Forwarded-Proto, and not from current endpoint. Change-Id: I3fafc4ef1cf56cb8f1cddc1a003a755e3f93c75c Closes-Bug: 1774460
This commit is contained in:
parent
1813f7c497
commit
d62d82b0fe
|
@ -99,7 +99,8 @@ def get_previous_link(request, items, id_key):
|
|||
marker = items[0][id_key]
|
||||
params['marker'] = marker
|
||||
params['page_reverse'] = True
|
||||
return "%s?%s" % (prepare_url(request.path_url), parse.urlencode(params))
|
||||
return "%s?%s" % (prepare_url(get_path_url(request)),
|
||||
parse.urlencode(params))
|
||||
|
||||
|
||||
def get_next_link(request, items, id_key):
|
||||
|
@ -109,7 +110,8 @@ def get_next_link(request, items, id_key):
|
|||
marker = items[-1][id_key]
|
||||
params['marker'] = marker
|
||||
params.pop('page_reverse', None)
|
||||
return "%s?%s" % (prepare_url(request.path_url), parse.urlencode(params))
|
||||
return "%s?%s" % (prepare_url(get_path_url(request)),
|
||||
parse.urlencode(params))
|
||||
|
||||
|
||||
def prepare_url(orig_url):
|
||||
|
@ -125,6 +127,21 @@ def prepare_url(orig_url):
|
|||
return parse.urlunsplit(url_parts).rstrip('/')
|
||||
|
||||
|
||||
def get_path_url(request):
|
||||
"""Return correct link if X-Forwarded-Proto exists in headers."""
|
||||
protocol = request.headers.get('X-Forwarded-Proto')
|
||||
parsed = parse.urlparse(request.path_url)
|
||||
|
||||
if protocol and parsed.scheme != protocol:
|
||||
new_parsed = parse.ParseResult(
|
||||
protocol, parsed.netloc,
|
||||
parsed.path, parsed.params,
|
||||
parsed.query, parsed.fragment)
|
||||
return parse.urlunparse(new_parsed)
|
||||
else:
|
||||
return request.path_url
|
||||
|
||||
|
||||
def get_limit_and_marker(request):
|
||||
"""Return marker, limit tuple from request.
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# under the License.
|
||||
|
||||
from oslo_config import cfg
|
||||
import webob
|
||||
|
||||
from neutron.api import api_common
|
||||
from neutron.tests import base
|
||||
|
@ -31,3 +32,40 @@ class PrepareUrlTestCase(base.BaseTestCase):
|
|||
requrl = 'http://neutron.example/sub/ports.json?test=1'
|
||||
expected = 'http://quantum.example/sub/ports.json?test=1'
|
||||
self.assertEqual(expected, api_common.prepare_url(requrl))
|
||||
|
||||
|
||||
class GetPathUrlTestCase(base.BaseTestCase):
|
||||
|
||||
def test_no_headers(self):
|
||||
base_http_url = 'http://neutron.example/sub/ports.json'
|
||||
base_https_url = 'https://neutron.example/sub/ports.json'
|
||||
path = ''
|
||||
|
||||
http_req = webob.Request.blank(path, base_url=base_http_url)
|
||||
https_req = webob.Request.blank(path, base_url=base_https_url)
|
||||
|
||||
# should be unchanged
|
||||
self.assertEqual(base_http_url, api_common.get_path_url(http_req))
|
||||
self.assertEqual(base_https_url, api_common.get_path_url(https_req))
|
||||
|
||||
def test_http_to_https(self):
|
||||
base_url = 'http://neutron.example/sub/ports.json'
|
||||
path = ''
|
||||
|
||||
request = webob.Request.blank(
|
||||
path, base_url=base_url, headers={'X-Forwarded-Proto': 'https'})
|
||||
|
||||
path_url = api_common.get_path_url(request)
|
||||
# should replace http:// with https://
|
||||
self.assertTrue(path_url.startswith("https://"))
|
||||
|
||||
def test_https_to_http(self):
|
||||
base_url = 'https://neutron.example/sub/ports.json'
|
||||
path = ''
|
||||
|
||||
request = webob.Request.blank(
|
||||
path, base_url=base_url, headers={'X-Forwarded-Proto': 'http'})
|
||||
|
||||
path_url = api_common.get_path_url(request)
|
||||
# should replace https:// with http://
|
||||
self.assertTrue(path_url.startswith("http://"))
|
||||
|
|
Loading…
Reference in New Issue