Merge lp:~jtv/maas/1.2-bug-1075597 into lp:maas/1.2

Proposed by Jeroen T. Vermeulen
Status: Merged
Approved by: Jeroen T. Vermeulen
Approved revision: no longer in the source branch.
Merged at revision: 1294
Proposed branch: lp:~jtv/maas/1.2-bug-1075597
Merge into: lp:maas/1.2
Diff against target: 177 lines (+70/-38)
4 files modified
src/maasserver/api.py (+5/-1)
src/maasserver/tests/test_api.py (+48/-10)
src/maasserver/utils/__init__.py (+10/-13)
src/maasserver/utils/tests/test_utils.py (+7/-14)
To merge this branch: bzr merge lp:~jtv/maas/1.2-bug-1075597
Reviewer Review Type Date Requested Status
Jeroen T. Vermeulen (community) Approve
Review via email: mp+133429@code.launchpad.net

Commit message

Backport trunk r1334: don't include the script_name prefix in build_absolute_uri; it was already in the path it appends.

Description of the change

To post a comment you must log in.
Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

Unmodified backport; self-approving.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/maasserver/api.py'
--- src/maasserver/api.py 2012-11-08 06:40:03 +0000
+++ src/maasserver/api.py 2012-11-08 09:34:41 +0000
@@ -1867,7 +1867,11 @@
1867def describe(request):1867def describe(request):
1868 """Return a description of the whole MAAS API.1868 """Return a description of the whole MAAS API.
18691869
1870 Returns a JSON object describing the whole MAAS API.1870 :param request: The http request for this document. This is used to
1871 derive the URL where the client expects to see the MAAS API.
1872 :return: A JSON object describing the whole MAAS API. Links to the API
1873 will use the same scheme and hostname that the client used in
1874 `request`.
1871 """1875 """
1872 from maasserver import urls_api as urlconf1876 from maasserver import urls_api as urlconf
1873 resources = [1877 resources = [
18741878
=== modified file 'src/maasserver/tests/test_api.py'
--- src/maasserver/tests/test_api.py 2012-11-08 06:40:03 +0000
+++ src/maasserver/tests/test_api.py 2012-11-08 09:34:41 +0000
@@ -38,7 +38,11 @@
38from celery.app import app_or_default38from celery.app import app_or_default
39from django.conf import settings39from django.conf import settings
40from django.contrib.auth.models import AnonymousUser40from django.contrib.auth.models import AnonymousUser
41from django.core.urlresolvers import reverse41import django.core.urlresolvers
42from django.core.urlresolvers import (
43 reverse,
44 get_script_prefix,
45 )
42from django.http import QueryDict46from django.http import QueryDict
43from django.test.client import RequestFactory47from django.test.client import RequestFactory
44from fixtures import Fixture48from fixtures import Fixture
@@ -4292,19 +4296,53 @@
4292 scenarios = multiply_scenarios(4296 scenarios = multiply_scenarios(
4293 scenarios_schemes, scenarios_paths)4297 scenarios_schemes, scenarios_paths)
42944298
4295 def test_handler_uris_are_absolute(self):4299 def make_params(self):
4296 server = factory.make_name("server").lower()4300 """Create parameters for http request, based on current scenario."""
4297 extra = {4301 return {
4298 "PATH_INFO": self.path_info,4302 "PATH_INFO": self.path_info,
4299 "SCRIPT_NAME": self.script_name,4303 "SCRIPT_NAME": self.script_name,
4300 "SERVER_NAME": server,4304 "SERVER_NAME": factory.make_name('server').lower(),
4301 "wsgi.url_scheme": self.scheme,4305 "wsgi.url_scheme": self.scheme,
4302 }4306 }
4303 request = RequestFactory().get(4307
4304 "/%s/describe" % factory.make_name("path"), **extra)4308 def get_description(self, params):
4309 """GET the API description (at a random API path), as JSON."""
4310 path = '/%s/describe' % factory.make_name('path')
4311 request = RequestFactory().get(path, **params)
4305 response = describe(request)4312 response = describe(request)
4306 self.assertEqual(httplib.OK, response.status_code, response.content)4313 self.assertEqual(
4307 description = json.loads(response.content)4314 httplib.OK, response.status_code,
4315 "API description failed with code %s:\n%s"
4316 % (response.status_code, response.content))
4317 return json.loads(response.content)
4318
4319 def patch_script_prefix(self, script_name):
4320 """Patch up Django's and Piston's notion of the script_name prefix.
4321
4322 This manipulates how Piston gets Django's version of script_name
4323 which it needs so that it can prefix script_name to URL paths.
4324 """
4325 # Patching up get_script_prefix doesn't seem to do the trick,
4326 # and patching it in the right module requires unwarranted
4327 # intimacy with Piston. So just go through the proper call and
4328 # set the prefix. But clean this up after the test or it will
4329 # break other tests!
4330 original_prefix = get_script_prefix()
4331 self.addCleanup(
4332 django.core.urlresolvers.set_script_prefix, original_prefix)
4333 django.core.urlresolvers.set_script_prefix(script_name)
4334
4335 def test_handler_uris_are_absolute(self):
4336 params = self.make_params()
4337 server = params['SERVER_NAME']
4338
4339 # Without this, the test wouldn't be able to detect accidental
4340 # duplication of the script_name portion of the URL path:
4341 # /MAAS/MAAS/api/...
4342 self.patch_script_prefix(self.script_name)
4343
4344 description = self.get_description(params)
4345
4308 expected_uri = AfterPreprocessing(4346 expected_uri = AfterPreprocessing(
4309 urlparse, MatchesStructure(4347 urlparse, MatchesStructure(
4310 scheme=Equals(self.scheme), hostname=Equals(server),4348 scheme=Equals(self.scheme), hostname=Equals(server),
43114349
=== modified file 'src/maasserver/utils/__init__.py'
--- src/maasserver/utils/__init__.py 2012-11-02 09:48:02 +0000
+++ src/maasserver/utils/__init__.py 2012-11-08 09:34:41 +0000
@@ -87,20 +87,17 @@
8787
8888
89def build_absolute_uri(request, path):89def build_absolute_uri(request, path):
90 """Given a full app-relative path, returns an absolute URI.90 """Return absolute URI corresponding to given absolute path.
9191
92 The path ordinarily starts with a forward-slash... imagine that you've92 :param request: An http request to the API. This is needed in order to
93 magically chroot'ed to your Django application; the path is the absolute93 figure out how the client is used to addressing
94 path to the view within that environment.94 the API on the network.
9595 :param path: The absolute http path to a given resource.
96 The URI returned uses the request to figure out how to make an absolute96 :return: Full, absolute URI to the resource, taking its networking
97 URL. This means that the URI returned will use the same IP address or97 portion from `request` but the rest from `path`.
98 alias that the request came in on.
99 """98 """
100 script_name = request.META["SCRIPT_NAME"]99 scheme = "https" if request.is_secure() else "http"
101 return "%s://%s%s%s" % (100 return "%s://%s%s" % (scheme, request.get_host(), path)
102 "https" if request.is_secure() else "http",
103 request.get_host(), script_name, path)
104101
105102
106def strip_domain(hostname):103def strip_domain(hostname):
107104
=== modified file 'src/maasserver/utils/tests/test_utils.py'
--- src/maasserver/utils/tests/test_utils.py 2012-11-02 09:48:02 +0000
+++ src/maasserver/utils/tests/test_utils.py 2012-11-08 09:34:41 +0000
@@ -134,12 +134,13 @@
134 "http://example.com:1234/fred",134 "http://example.com:1234/fred",
135 build_absolute_uri(request, "/fred"))135 build_absolute_uri(request, "/fred"))
136136
137 def test_script_name_is_prefixed(self):137 def test_script_name_is_ignored(self):
138 # The script name is always prefixed to the given path.138 # The given path already includes the script_name, so the
139 # script_name passed in the request is not included again.
139 request = self.make_request(script_name="/foo/bar")140 request = self.make_request(script_name="/foo/bar")
140 self.assertEqual(141 self.assertEqual(
141 "http://example.com/foo/bar/fred",142 "http://example.com/foo/bar/fred",
142 build_absolute_uri(request, "/fred"))143 build_absolute_uri(request, "/foo/bar/fred"))
143144
144 def test_secure(self):145 def test_secure(self):
145 request = self.make_request(port=443, is_secure=True)146 request = self.make_request(port=443, is_secure=True)
@@ -153,21 +154,13 @@
153 "https://example.com:9443/fred",154 "https://example.com:9443/fred",
154 build_absolute_uri(request, "/fred"))155 build_absolute_uri(request, "/fred"))
155156
156 def test_no_leading_forward_slash(self):
157 # No attempt is made to ensure that the given path is separated from
158 # the to-be-prefixed path.
159 request = self.make_request(script_name="/foo")
160 self.assertEqual(
161 "http://example.com/foobar",
162 build_absolute_uri(request, "bar"))
163
164 def test_preserve_two_leading_slashes(self):157 def test_preserve_two_leading_slashes(self):
165 # Whilst this shouldn't ordinarily happen, two leading slashes in the158 # Whilst this shouldn't ordinarily happen, two leading slashes in the
166 # path should be preserved, and not treated specially.159 # path should be preserved, and not treated specially.
167 request = self.make_request(script_name="//foo")160 request = self.make_request()
168 self.assertEqual(161 self.assertEqual(
169 "http://example.com//foo/fred",162 "http://example.com//foo",
170 build_absolute_uri(request, "/fred"))163 build_absolute_uri(request, "//foo"))
171164
172165
173class TestStripDomain(TestCase):166class TestStripDomain(TestCase):

Subscribers

People subscribed via source and target branches

to status/vote changes: