From: Brian Warner Date: Mon, 17 Jan 2011 07:47:51 +0000 (-0800) Subject: Tolerate Twisted-10.2's endpoints, patch by David-Sarah. Closes #1286. X-Git-Url: https://git.rkrishnan.org/vdrive/%22file:/frontends/%3C?a=commitdiff_plain;h=09a2241471c56f0aa1eafb928e5b09f7124e5640;p=tahoe-lafs%2Ftahoe-lafs.git Tolerate Twisted-10.2's endpoints, patch by David-Sarah. Closes #1286. The service generated by strports.service() changed in 10.2, and the ugly private-attribute-reading hack we used to glean a kernel-allocated port number (e.g. when using "tcp:0", especially during unit tests) broke, causing Tahoe to be completely unusable with Twisted-10.2 . The new ugly private-attribute-reading hack starts by figuring out what sort of service was generated, then reads different attributes accordingly. This also hushes a warning when using schemeless strports strings like "0" or "3456", by quietly prepending a "tcp:" scheme, since 10.2 complains about those. It also adds getURL() and getPortnum() accessors to the "webish" service, rather than having unit tests dig through _url and _portnum and such to find out what they are. --- diff --git a/src/allmydata/test/common.py b/src/allmydata/test/common.py index fa032ecd..e8117bf7 100644 --- a/src/allmydata/test/common.py +++ b/src/allmydata/test/common.py @@ -503,14 +503,10 @@ class SystemTestMixin(pollmixin.PollMixin, testutil.StallMixin): def _connected(res): log.msg("CONNECTED") # now find out where the web port was - l = self.clients[0].getServiceNamed("webish").listener - port = l._port.getHost().port - self.webish_url = "http://localhost:%d/" % port + self.webish_url = self.clients[0].getServiceNamed("webish").getURL() if self.numclients >=4: # and the helper-using webport - l = self.clients[3].getServiceNamed("webish").listener - port = l._port.getHost().port - self.helper_webish_url = "http://localhost:%d/" % port + self.helper_webish_url = self.clients[3].getServiceNamed("webish").getURL() d.addCallback(_connected) return d @@ -541,9 +537,7 @@ class SystemTestMixin(pollmixin.PollMixin, testutil.StallMixin): def _maybe_get_webport(res): if num == 0: # now find out where the web port was - l = self.clients[0].getServiceNamed("webish").listener - port = l._port.getHost().port - self.webish_url = "http://localhost:%d/" % port + self.webish_url = self.clients[0].getServiceNamed("webish").getURL() d.addCallback(_maybe_get_webport) return d diff --git a/src/allmydata/test/no_network.py b/src/allmydata/test/no_network.py index f19ad68b..554a75f6 100644 --- a/src/allmydata/test/no_network.py +++ b/src/allmydata/test/no_network.py @@ -287,10 +287,10 @@ class GridTestMixin: num_servers=num_servers, client_config_hooks=client_config_hooks) self.g.setServiceParent(self.s) - self.client_webports = [c.getServiceNamed("webish").listener._port.getHost().port + self.client_webports = [c.getServiceNamed("webish").getPortnum() + for c in self.g.clients] + self.client_baseurls = [c.getServiceNamed("webish").getURL() for c in self.g.clients] - self.client_baseurls = ["http://localhost:%d/" % p - for p in self.client_webports] def get_clientdir(self, i=0): return self.g.clients[i].basedir diff --git a/src/allmydata/test/test_web.py b/src/allmydata/test/test_web.py index f68e98d8..615429cb 100644 --- a/src/allmydata/test/test_web.py +++ b/src/allmydata/test/test_web.py @@ -169,8 +169,10 @@ class WebMixin(object): self.ws = webish.WebishServer(self.s, "0", staticdir=self.staticdir, clock=self.clock) self.ws.setServiceParent(self.s) - self.webish_port = port = self.ws.listener._port.getHost().port - self.webish_url = "http://localhost:%d" % port + self.webish_port = self.ws.getPortnum() + self.webish_url = self.ws.getURL() + assert self.webish_url.endswith("/") + self.webish_url = self.webish_url[:-1] # these tests add their own / l = [ self.s.create_dirnode() for x in range(6) ] d = defer.DeferredList(l) diff --git a/src/allmydata/webish.py b/src/allmydata/webish.py index 2cd77aa7..5ab9337d 100644 --- a/src/allmydata/webish.py +++ b/src/allmydata/webish.py @@ -1,4 +1,4 @@ -import time +import re, time from twisted.application import service, strports, internet from twisted.web import http from twisted.internet import defer @@ -149,30 +149,68 @@ class WebishServer(service.MultiService): self.site.remember(MyExceptionHandler(), inevow.ICanHandleException) if staticdir: self.root.putChild("static", static.File(staticdir)) + if re.search(r'^\d', webport): + webport = "tcp:"+webport # twisted warns about bare "0" or "3456" s = strports.service(webport, site) s.setServiceParent(self) + + self._scheme = None + self._portnum = None + self._url = None self.listener = s # stash it so the tests can query for the portnum + self._started = defer.Deferred() if nodeurl_path: self._started.addCallback(self._write_nodeurl_file, nodeurl_path) + def getURL(self): + assert self._url + return self._url + def getPortnum(self): + assert self._portnum + return self._portnum + def startService(self): - service.MultiService.startService(self) - self._started.callback(None) + def _got_port(lp): + self._portnum = lp.getHost().port + # what is our webport? + assert self._scheme + self._url = "%s://127.0.0.1:%d/" % (self._scheme, self._portnum) + self._started.callback(None) + return lp + def _fail(f): + self._started.errback(f) + return f - def _write_nodeurl_file(self, junk, nodeurl_path): - # what is our webport? + service.MultiService.startService(self) s = self.listener - if isinstance(s, internet.TCPServer): - base_url = "http://127.0.0.1:%d/" % s._port.getHost().port + if hasattr(s, 'endpoint') and hasattr(s, '_waitingForPort'): + # Twisted 10.2 gives us a StreamServerEndpointService. This is + # ugly but should do for now. + classname = s.endpoint.__class__.__name__ + if classname.startswith('SSL'): + self._scheme = 'https' + else: + self._scheme = 'http' + s._waitingForPort.addCallbacks(_got_port, _fail) + elif isinstance(s, internet.TCPServer): + # Twisted <= 10.1 + self._scheme = 'http' + _got_port(s._port) elif isinstance(s, internet.SSLServer): - base_url = "https://127.0.0.1:%d/" % s._port.getHost().port + # Twisted <= 10.1 + self._scheme = 'https' + _got_port(s._port) else: - base_url = None - if base_url: + # who knows, probably some weirdo future version of Twisted + self._started.errback(AssertionError("couldn't find out the scheme or port for the web-API server")) + + + def _write_nodeurl_file(self, junk, nodeurl_path): + if self._url: f = open(nodeurl_path, 'wb') # this file is world-readable - f.write(base_url + "\n") + f.write(self._url + "\n") f.close() class IntroducerWebishServer(WebishServer):