From 76b7b9d8350e8a918d4f03335ac556f55009d105 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Thu, 23 Oct 2008 15:56:58 -0700 Subject: [PATCH] webapi: make the /operations/ 't=status' qualifier optional, remove it from examples --- docs/webapi.txt | 42 ++++++++++++++++----------------- src/allmydata/test/test_web.py | 7 +++++- src/allmydata/web/operations.py | 9 +++---- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/docs/webapi.txt b/docs/webapi.txt index a168bb77..14477399 100644 --- a/docs/webapi.txt +++ b/docs/webapi.txt @@ -200,8 +200,8 @@ are created by the client, and passed in as a an "ophandle=" query argument to the POST or PUT request which starts the operation. The following operations can then be used to retrieve status: -GET /operations/$HANDLE?t=status&output=HTML -GET /operations/$HANDLE?t=status&output=JSON +GET /operations/$HANDLE?output=HTML (with or without t=status) +GET /operations/$HANDLE?output=JSON (same) These two retrieve the current status of the given operation. Each operation presents a different sort of information, but in general the page retrieved @@ -220,30 +220,30 @@ POST /operations/$HANDLE?t=cancel cancelled. If the operation handle has already expired (see below), this POST will return a 404, which indicates that the operation is no longer running (either it was completed or terminated). The response body will be - the same as a t=status on this operation handle, and the handle will be - expired immediately afterwards. + the same as a GET /operations/$HANDLE on this operation handle, and the + handle will be expired immediately afterwards. The operation handle will eventually expire, to avoid consuming an unbounded amount of memory. The handle's time-to-live can be reset at any time, by passing a retain-for= argument (with a count of seconds) to either the -initial POST that starts the operation, or the subsequent 'GET t=status' -request which asks about the operation. For example, if a 'GET -/operations/$HANDLE?t=status&output=JSON&retain-for=600' query is performed, -the handle will remain active for 600 seconds (10 minutes) after the GET was +initial POST that starts the operation, or the subsequent GET request which +asks about the operation. For example, if a 'GET +/operations/$HANDLE?output=JSON&retain-for=600' query is performed, the +handle will remain active for 600 seconds (10 minutes) after the GET was received. -In addition, if the GET t=status includes a release-after-complete=True -argument, and the operation has completed, the operation handle will be -released immediately. +In addition, if the GET includes a release-after-complete=True argument, and +the operation has completed, the operation handle will be released +immediately. If a retain-for= argument is not used, the default handle lifetimes are: * handles will remain valid at least until their operation finishes * uncollected handles for finished operations (i.e. handles for operations - which have finished but for which the t=status page has not been accessed - since completion) will remain valid for one hour, or for the total time - consumed by the operation, whichever is greater. - * collected handles (i.e. the t=status page has been retrieved at least once + which have finished but for which the GET page has not been accessed since + completion) will remain valid for one hour, or for the total time consumed + by the operation, whichever is greater. + * collected handles (i.e. the GET page has been retrieved at least once since the operation completed) will remain valid for ten minutes. @@ -819,11 +819,11 @@ POST $URL?t=start-deep-check (must add &ophandle=XYZ) deep-check operation will continue to run in the background, and the /operations page should be used to find out when the operation is done. - The HTML /operations/$HANDLE?t=status page for incomplete operations will - contain a meta-refresh tag, set to 60 seconds, so that a browser which uses + The HTML /operations/$HANDLE page for incomplete operations will contain a + meta-refresh tag, set to 60 seconds, so that a browser which uses deep-check will automatically poll until the operation has completed. - The JSON page (/options/$HANDLE?t=status&output=JSON) will contain a + The JSON page (/options/$HANDLE?output=JSON) will contain a machine-readable JSON dictionary with the following keys: finished: a boolean, True if the operation is complete, else False. Some @@ -944,8 +944,8 @@ POST $DIRURL?t=start-manifest (must add &ophandle=XYZ) gives immediate access to every object in the virtual filesystem subtree. This operation uses the same ophandle= mechanism as deep-check. The - corresponding /operations/$HANDLE?t=status page has three different forms. - The default is output=HTML. + corresponding /operations/$HANDLE page has three different forms. The + default is output=HTML. If output=text is added to the query args, the results will be a text/plain list. The first line is special: it is either "finished: yes" or "finished: @@ -970,7 +970,7 @@ POST $DIRURL?t=start-deep-size (must add &ophandle=XYZ) take expansion or encoding overhead into account. Later versions of the code may improve this estimate upwards. - The t=status output consists of two lines of text: + The /operations/$HANDLE status output consists of two lines of text: finished: yes size: 1234 diff --git a/src/allmydata/test/test_web.py b/src/allmydata/test/test_web.py index 251da9cd..0d9ac956 100644 --- a/src/allmydata/test/test_web.py +++ b/src/allmydata/test/test_web.py @@ -854,6 +854,11 @@ class Web(WebMixin, testutil.StallMixin, unittest.TestCase): self.failUnless(self._sub_uri in manifest) self.failUnless("sub/baz.txt" in manifest) d.addCallback(_got_html) + + # both t=status and unadorned GET should be identical + d.addCallback(lambda res: self.GET("/operations/125")) + d.addCallback(_got_html) + d.addCallback(getman, "html") d.addCallback(_got_html) d.addCallback(getman, "text") @@ -1599,7 +1604,7 @@ class Web(WebMixin, testutil.StallMixin, unittest.TestCase): def test_POST_DIRURL_deepcheck(self): def _check_redirect(statuscode, target): self.failUnlessEqual(statuscode, str(http.FOUND)) - self.failUnless(target.endswith("/operations/123?t=status")) + self.failUnless(target.endswith("/operations/123")) d = self.shouldRedirect2("test_POST_DIRURL_deepcheck", _check_redirect, self.POST, self.public_url, t="start-deep-check", ophandle="123") diff --git a/src/allmydata/web/operations.py b/src/allmydata/web/operations.py index 080f8dbb..e8e5a85b 100644 --- a/src/allmydata/web/operations.py +++ b/src/allmydata/web/operations.py @@ -60,10 +60,10 @@ class OphandleTable(rend.Page, service.Service): def redirect_to(self, ctx): ophandle = get_arg(ctx, "ophandle") assert ophandle - target = get_root(ctx) + "/operations/" + ophandle + "?t=status" + target = get_root(ctx) + "/operations/" + ophandle output = get_arg(ctx, "output") if output: - target = target + "&output=%s" % output + target = target + "?output=%s" % output return url.URL.fromString(target) def childFactory(self, ctx, name): @@ -73,8 +73,9 @@ class OphandleTable(rend.Page, service.Service): NOT_FOUND) (monitor, renderer, when_added) = self.handles[ophandle] + request = IRequest(ctx) t = get_arg(ctx, "t", "status") - if t == "cancel": + if t == "cancel" and request.method == "POST": monitor.cancel() # return the status anyways, but release the handle self._release_ophandle(ophandle) @@ -124,7 +125,7 @@ class ReloadMixin: # url.gethere would break a proxy, so the correct thing to do is # req.path[-1] + queryargs ophandle = req.prepath[-1] - reload_target = ophandle + "?t=status&output=html" + reload_target = ophandle + "?output=html" cancel_target = ophandle + "?t=cancel" cancel_button = T.form(action=cancel_target, method="POST", enctype="multipart/form-data")[ -- 2.45.2