Merge lp:~bjornt/launchpad/bug-376990 into lp:launchpad/db-devel

Proposed by Björn Tillenius
Status: Merged
Approved by: Brad Crittenden
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~bjornt/launchpad/bug-376990
Merge into: lp:launchpad/db-devel
Diff against target: None lines
To merge this branch: bzr merge lp:~bjornt/launchpad/bug-376990
Reviewer Review Type Date Requested Status
Brad Crittenden (community) mentor Approve
Leonard Richardson (community) Approve
Review via email: mp+9320@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Björn Tillenius (bjornt) wrote :

This branch makes canonical_url() produce browser URLs, even though the
current request is a web service request. We have some problems that API
URLs are used instead of browser URLs, for example in XHTML.
presentations and when e-mail notifications are generated inside API.
methods.

IMHO, canonical_url() should be split into two functions, but it's too.
late to do that now. I'd like one function that always returns a browser
URL, and one that returns either a browser or web service URL, depending
on which request is currently used. That's basically how I made.
canonical_url() work with this change. If no request is explicitly.
passed to it, a browser URL is always returned. In the case where you.
may want an API URL, you have to pass in the current request explicitly.
That's why I had to pass in the request to canonical_url() in the.
/people/foo rediretor, since it's used in both the app and web service
servers. Basically all code that redirects objects to canonical_url().
will need to pass in the request explicitly. At the moment all tests.
pass, but we might find a few bugs later. I don't expect this to be a.
big deal, though.

In this branch I also made canonical_url.txt run in FunctionalLayer, so
that it runs a bit faster.

BTW, I'm not going to land this branch before someone with more web.
service foo has commented on it, but I have discussed this approach with.
them already.

Revision history for this message
Leonard Richardson (leonardr) wrote :

Approved.*

review: Approve
Revision history for this message
Leonard Richardson (leonardr) wrote :

> Approved.*

I'm not totally happy with this solution, but there are so many call sites that changing the default behavior is the only real way to fix this.

Revision history for this message
Brad Crittenden (bac) wrote :

* line 11: s/want/wants
* line 13: typo: therefore
* The last sentence reads better as:
Therefore, if no request is explicitly given canonical_url() returns the browser
URL, even if the current request is a web service request.

Thanks for making the change to FunctionalLayer. Did you measure the improvement?

review: Approve (mentor)
Revision history for this message
Björn Tillenius (bjornt) wrote :

On Tue, Jul 28, 2009 at 01:13:29PM -0000, Brad Crittenden wrote:
> Review: Approve mentor
> * line 11: s/want/wants
> * line 13: typo: therefore

Why do I always make that typo? :)

> * The last sentence reads better as:
> Therefore, if no request is explicitly given canonical_url() returns the browser
> URL, even if the current request is a web service request.

Thanks, I'll fix it.

>
> Thanks for making the change to FunctionalLayer. Did you measure the
> improvement?

Yes. It's still quite slow, but took it down from 40 seconds to 20
seconds.

--
Björn Tillenius | https://launchpad.net/~bjornt

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/canonical/launchpad/doc/canonical_url.txt'
--- lib/canonical/launchpad/doc/canonical_url.txt 2009-05-13 16:51:38 +0000
+++ lib/canonical/launchpad/doc/canonical_url.txt 2009-07-27 13:45:52 +0000
@@ -492,6 +492,37 @@
492 NoCanonicalUrl: No url for <...ObjectThatHasUrl...> because <...object...> broke the chain.492 NoCanonicalUrl: No url for <...ObjectThatHasUrl...> because <...object...> broke the chain.
493493
494494
495== canonical_url in the web service ==
496
497canonical_url() is sometimes used in code that doesn't have direct
498access to the current request, and always want a URL that can be used in
499a browser (for example e-mail notifications or XHTML representations of
500objects). Therefor, if no request is explicitly given, and the current
501request is a web service request, canonical_url() returns the browser
502URL.
503
504 >>> from zope.app.security.principalregistry import (
505 ... UnauthenticatedPrincipal)
506 >>> from canonical.launchpad.webapp.servers import WebServiceTestRequest
507 >>> from canonical.launchpad.webapp.interaction import setupInteraction
508 >>> from lazr.restful.utils import get_current_browser_request
509 >>> anonymous = UnauthenticatedPrincipal(None, None, None)
510 >>> api_request = WebServiceTestRequest()
511 >>> setupInteraction(anonymous, participation=api_request)
512 >>> get_current_browser_request() is api_request
513 True
514
515 >>> canonical_url(countryset_instance)
516 u'http://launchpad.dev/countries'
517
518
519If an URL that can be used in the web service is required, a web service
520request has to be passed in explicitly.
521
522 >>> canonical_url(countryset_instance, request=api_request)
523 u'http://api.launchpad.dev/countries'
524
525
495== The end ==526== The end ==
496527
497We've finished with our interfaces and utility component, so remove them from528We've finished with our interfaces and utility component, so remove them from
498529
=== modified file 'lib/canonical/launchpad/ftests/test_system_documentation.py'
--- lib/canonical/launchpad/ftests/test_system_documentation.py 2009-07-17 00:26:05 +0000
+++ lib/canonical/launchpad/ftests/test_system_documentation.py 2009-07-24 08:59:59 +0000
@@ -273,6 +273,12 @@
273 tearDown=updateRemoteProductTeardown,273 tearDown=updateRemoteProductTeardown,
274 layer=LaunchpadZopelessLayer274 layer=LaunchpadZopelessLayer
275 ),275 ),
276 'canonical_url.txt': LayeredDocFileSuite(
277 '../doc/canonical_url.txt',
278 setUp=setUp,
279 tearDown=tearDown,
280 layer=FunctionalLayer,
281 ),
276 }282 }
277283
278284
279285
=== modified file 'lib/canonical/launchpad/webapp/publisher.py'
--- lib/canonical/launchpad/webapp/publisher.py 2009-06-25 05:30:52 +0000
+++ lib/canonical/launchpad/webapp/publisher.py 2009-07-24 12:52:33 +0000
@@ -38,7 +38,7 @@
38from zope.traversing.browser.interfaces import IAbsoluteURL38from zope.traversing.browser.interfaces import IAbsoluteURL
3939
40from canonical.cachedproperty import cachedproperty40from canonical.cachedproperty import cachedproperty
41from canonical.launchpad.layers import setFirstLayer41from canonical.launchpad.layers import setFirstLayer, WebServiceLayer
42from canonical.launchpad.webapp.vhosts import allvhosts42from canonical.launchpad.webapp.vhosts import allvhosts
43from canonical.launchpad.webapp.interfaces import (43from canonical.launchpad.webapp.interfaces import (
44 ICanonicalUrlData, ILaunchBag, ILaunchpadApplication, ILaunchpadContainer,44 ICanonicalUrlData, ILaunchBag, ILaunchpadApplication, ILaunchpadContainer,
@@ -463,6 +463,21 @@
463 # Look for a request from the interaction.463 # Look for a request from the interaction.
464 current_request = get_current_browser_request()464 current_request = get_current_browser_request()
465 if current_request is not None:465 if current_request is not None:
466 if WebServiceLayer.providedBy(current_request):
467 from canonical.launchpad.webapp.publication import (
468 LaunchpadBrowserPublication)
469 from canonical.launchpad.webapp.servers import (
470 LaunchpadBrowserRequest)
471 current_request = LaunchpadBrowserRequest(
472 current_request.bodyStream.getCacheStream(),
473 dict(current_request.environment))
474 current_request.setPublication(
475 LaunchpadBrowserPublication(None))
476 current_request.setVirtualHostRoot(names=[])
477 main_root_url = current_request.getRootURL(
478 'mainsite')
479 current_request._app_server = main_root_url.rstrip('/')
480
466 request = current_request481 request = current_request
467482
468 if view_name is not None:483 if view_name is not None:
469484
=== modified file 'lib/lp/registry/browser/person.py'
--- lib/lp/registry/browser/person.py 2009-07-20 15:27:26 +0000
+++ lib/lp/registry/browser/person.py 2009-07-27 13:37:23 +0000
@@ -616,14 +616,16 @@
616 if person is None:616 if person is None:
617 raise NotFoundError(name)617 raise NotFoundError(name)
618 # Redirect to /~name618 # Redirect to /~name
619 return self.redirectSubTree(canonical_url(person))619 return self.redirectSubTree(
620 canonical_url(person, request=self.request))
620621
621 @stepto('+me')622 @stepto('+me')
622 def me(self):623 def me(self):
623 me = getUtility(ILaunchBag).user624 me = getUtility(ILaunchBag).user
624 if me is None:625 if me is None:
625 raise Unauthorized("You need to be logged in to view this URL.")626 raise Unauthorized("You need to be logged in to view this URL.")
626 return self.redirectSubTree(canonical_url(me), status=303)627 return self.redirectSubTree(
628 canonical_url(me, request=self.request), status=303)
627629
628630
629class PersonSetContextMenu(ContextMenu):631class PersonSetContextMenu(ContextMenu):

Subscribers

People subscribed via source and target branches

to status/vote changes: