server: give old 0.4.0 senders a "you must upgrade" error
Without this, old senders will throw a messy 404 traceback when talking to a modern server. Unfortunately 0.4.0 receivers don't make API calls in the right order, so they throw a 404 before seeing our "you need to upgrade" message.
This commit is contained in:
parent
ca5f79233c
commit
b83062701d
7
NEWS.md
7
NEWS.md
|
@ -1,6 +1,13 @@
|
|||
|
||||
User-visible changes in "magic-wormhole":
|
||||
|
||||
## Release ?? (??)
|
||||
|
||||
* Arrange for 0.4.0 senders to print an error message when connecting to a
|
||||
current (0.5.0) server, instead of an ugly stack trace. Unfortunately 0.4.0
|
||||
receivers still display the traceback, since they don't check the welcome
|
||||
message before using a missing API.
|
||||
|
||||
## Release 0.5.0 (07-Oct-2015)
|
||||
|
||||
* Change the CLI to merge send-file with send-text, and receive-file with
|
||||
|
|
|
@ -63,6 +63,9 @@ class ChannelLister(resource.Resource):
|
|||
self._relay = relay
|
||||
|
||||
def render_GET(self, request):
|
||||
if b"appid" not in request.args:
|
||||
e = NeedToUpgradeErrorResource(self._relay.welcome)
|
||||
return e.get_message()
|
||||
appid = request.args[b"appid"][0].decode("utf-8")
|
||||
#print("LIST", appid)
|
||||
app = self._relay.get_app(appid)
|
||||
|
@ -95,6 +98,29 @@ class Allocator(resource.Resource):
|
|||
"channelid": channelid}
|
||||
return (json.dumps(data)+"\n").encode("utf-8")
|
||||
|
||||
def getChild(self, path, req):
|
||||
# wormhole-0.4.0 "send" started with "POST /allocate/SIDE".
|
||||
# wormhole-0.5.0 changed that to "POST /allocate". We catch the old
|
||||
# URL here to deliver a nicer error message (with upgrade
|
||||
# instructions) than an ugly 404.
|
||||
return NeedToUpgradeErrorResource(self._relay.welcome)
|
||||
|
||||
class NeedToUpgradeErrorResource(resource.Resource):
|
||||
def __init__(self, welcome):
|
||||
resource.Resource.__init__(self)
|
||||
w = welcome.copy()
|
||||
w["error"] = "Sorry, you must upgrade your client to use this server."
|
||||
message = {"welcome": w}
|
||||
self._message = (json.dumps(message)+"\n").encode("utf-8")
|
||||
def get_message(self):
|
||||
return self._message
|
||||
def render_POST(self, request):
|
||||
return self._message
|
||||
def render_GET(self, request):
|
||||
return self._message
|
||||
def getChild(self, path, req):
|
||||
return self
|
||||
|
||||
class Adder(resource.Resource):
|
||||
def __init__(self, relay):
|
||||
resource.Resource.__init__(self)
|
||||
|
@ -311,6 +337,15 @@ class Relay(resource.Resource, service.MultiService):
|
|||
self.putChild(b"get", Getter(self))
|
||||
self.putChild(b"deallocate", Deallocator(self))
|
||||
|
||||
def getChild(self, path, req):
|
||||
# 0.4.0 used "POST /CID/SIDE/post/MSGNUM"
|
||||
# 0.5.0 replaced it with "POST /add (json body)"
|
||||
# give a nicer error message to old clients
|
||||
if (len(req.postpath) >= 2
|
||||
and req.postpath[1] in (b"post", b"poll", b"deallocate")):
|
||||
return NeedToUpgradeErrorResource(self.welcome)
|
||||
return resource.NoResource("No such child resource.")
|
||||
|
||||
def get_app(self, appid):
|
||||
assert isinstance(appid, type(u""))
|
||||
if not appid in self._apps:
|
||||
|
|
|
@ -165,6 +165,35 @@ class API(ServerBase, unittest.TestCase):
|
|||
|
||||
return d
|
||||
|
||||
UPGRADE_ERROR = "Sorry, you must upgrade your client to use this server."
|
||||
def test_old_allocate(self):
|
||||
# 0.4.0 used "POST /allocate/SIDE".
|
||||
# 0.5.0 replaced it with "POST /allocate".
|
||||
# test that an old client gets a useful error message, not a 404.
|
||||
d = self.post("allocate/abc", {})
|
||||
def _check(data):
|
||||
self.failUnlessEqual(data["welcome"]["error"], self.UPGRADE_ERROR)
|
||||
d.addCallback(_check)
|
||||
return d
|
||||
|
||||
def test_old_list(self):
|
||||
# 0.4.0 used "GET /list".
|
||||
# 0.5.0 replaced it with "GET /list?appid="
|
||||
d = self.get("list", {}) # no appid
|
||||
def _check(data):
|
||||
self.failUnlessEqual(data["welcome"]["error"], self.UPGRADE_ERROR)
|
||||
d.addCallback(_check)
|
||||
return d
|
||||
|
||||
def test_old_post(self):
|
||||
# 0.4.0 used "POST /CID/SIDE/post/MSGNUM"
|
||||
# 0.5.0 replaced it with "POST /add (json body)"
|
||||
d = self.post("1/abc/post/pake", {})
|
||||
def _check(data):
|
||||
self.failUnlessEqual(data["welcome"]["error"], self.UPGRADE_ERROR)
|
||||
d.addCallback(_check)
|
||||
return d
|
||||
|
||||
def add_message(self, message, side="abc", phase="1"):
|
||||
return self.post("add",
|
||||
{"appid": "app1",
|
||||
|
|
Loading…
Reference in New Issue
Block a user