mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-01-31 08:25:35 +00:00
Merge pull request #819 from sajith/3425.return-errorpage-from-root
Return ErrorPage from web.root Fixes ticket:3425
This commit is contained in:
commit
c2e9d6057f
0
newsfragments/3425.minor
Normal file
0
newsfragments/3425.minor
Normal file
@ -2,6 +2,8 @@ from mock import Mock
|
|||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
from twisted.trial import unittest
|
from twisted.trial import unittest
|
||||||
from twisted.web.template import Tag
|
from twisted.web.template import Tag
|
||||||
from twisted.web.test.requesthelper import DummyRequest
|
from twisted.web.test.requesthelper import DummyRequest
|
||||||
@ -14,12 +16,14 @@ from ...storage_client import (
|
|||||||
from ...web.root import RootElement
|
from ...web.root import RootElement
|
||||||
from ...util.connection_status import ConnectionStatus
|
from ...util.connection_status import ConnectionStatus
|
||||||
from allmydata.web.root import URIHandler
|
from allmydata.web.root import URIHandler
|
||||||
from allmydata.web.common import WebError
|
|
||||||
from allmydata.client import _Client
|
from allmydata.client import _Client
|
||||||
|
|
||||||
from hypothesis import given
|
from hypothesis import given
|
||||||
from hypothesis.strategies import text
|
from hypothesis.strategies import text
|
||||||
|
|
||||||
|
from .common import (
|
||||||
|
assert_soup_has_tag_with_content,
|
||||||
|
)
|
||||||
|
|
||||||
from ..common import (
|
from ..common import (
|
||||||
EMPTY_CLIENT_CONFIG,
|
EMPTY_CLIENT_CONFIG,
|
||||||
@ -57,8 +61,19 @@ class RenderSlashUri(unittest.TestCase):
|
|||||||
A (trivially) invalid capbility is an error
|
A (trivially) invalid capbility is an error
|
||||||
"""
|
"""
|
||||||
self.request.args[b"uri"] = [b"not a capability"]
|
self.request.args[b"uri"] = [b"not a capability"]
|
||||||
with self.assertRaises(WebError):
|
response_body = self.res.render_GET(self.request)
|
||||||
self.res.render_GET(self.request)
|
|
||||||
|
soup = BeautifulSoup(response_body, 'html5lib')
|
||||||
|
|
||||||
|
assert_soup_has_tag_with_content(
|
||||||
|
self, soup, "title", "400 - Error",
|
||||||
|
)
|
||||||
|
assert_soup_has_tag_with_content(
|
||||||
|
self, soup, "h1", "Error",
|
||||||
|
)
|
||||||
|
assert_soup_has_tag_with_content(
|
||||||
|
self, soup, "p", "Invalid capability",
|
||||||
|
)
|
||||||
|
|
||||||
@given(
|
@given(
|
||||||
text()
|
text()
|
||||||
@ -68,8 +83,19 @@ class RenderSlashUri(unittest.TestCase):
|
|||||||
Let hypothesis try a bunch of invalid capabilities
|
Let hypothesis try a bunch of invalid capabilities
|
||||||
"""
|
"""
|
||||||
self.request.args[b"uri"] = [cap.encode('utf8')]
|
self.request.args[b"uri"] = [cap.encode('utf8')]
|
||||||
with self.assertRaises(WebError):
|
response_body = self.res.render_GET(self.request)
|
||||||
self.res.render_GET(self.request)
|
|
||||||
|
soup = BeautifulSoup(response_body, 'html5lib')
|
||||||
|
|
||||||
|
assert_soup_has_tag_with_content(
|
||||||
|
self, soup, "title", "400 - Error",
|
||||||
|
)
|
||||||
|
assert_soup_has_tag_with_content(
|
||||||
|
self, soup, "h1", "Error",
|
||||||
|
)
|
||||||
|
assert_soup_has_tag_with_content(
|
||||||
|
self, soup, "p", "Invalid capability",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class RenderServiceRow(unittest.TestCase):
|
class RenderServiceRow(unittest.TestCase):
|
||||||
|
@ -34,11 +34,13 @@ from allmydata.web import storage
|
|||||||
from allmydata.web.common import (
|
from allmydata.web.common import (
|
||||||
abbreviate_size,
|
abbreviate_size,
|
||||||
WebError,
|
WebError,
|
||||||
|
exception_to_child,
|
||||||
get_arg,
|
get_arg,
|
||||||
MultiFormatResource,
|
MultiFormatResource,
|
||||||
SlotsSequenceElement,
|
SlotsSequenceElement,
|
||||||
get_format,
|
get_format,
|
||||||
get_mutable_type,
|
get_mutable_type,
|
||||||
|
render_exception,
|
||||||
render_time_delta,
|
render_time_delta,
|
||||||
render_time,
|
render_time,
|
||||||
render_time_attr,
|
render_time_attr,
|
||||||
@ -58,6 +60,7 @@ class URIHandler(resource.Resource, object):
|
|||||||
super(URIHandler, self).__init__()
|
super(URIHandler, self).__init__()
|
||||||
self.client = client
|
self.client = client
|
||||||
|
|
||||||
|
@render_exception
|
||||||
def render_GET(self, req):
|
def render_GET(self, req):
|
||||||
"""
|
"""
|
||||||
Historically, accessing this via "GET /uri?uri=<capabilitiy>"
|
Historically, accessing this via "GET /uri?uri=<capabilitiy>"
|
||||||
@ -88,6 +91,7 @@ class URIHandler(resource.Resource, object):
|
|||||||
redir_uri = redir_uri.add(k.decode('utf8'), v.decode('utf8'))
|
redir_uri = redir_uri.add(k.decode('utf8'), v.decode('utf8'))
|
||||||
return redirectTo(redir_uri.to_text().encode('utf8'), req)
|
return redirectTo(redir_uri.to_text().encode('utf8'), req)
|
||||||
|
|
||||||
|
@render_exception
|
||||||
def render_PUT(self, req):
|
def render_PUT(self, req):
|
||||||
"""
|
"""
|
||||||
either "PUT /uri" to create an unlinked file, or
|
either "PUT /uri" to create an unlinked file, or
|
||||||
@ -109,6 +113,7 @@ class URIHandler(resource.Resource, object):
|
|||||||
)
|
)
|
||||||
raise WebError(errmsg, http.BAD_REQUEST)
|
raise WebError(errmsg, http.BAD_REQUEST)
|
||||||
|
|
||||||
|
@render_exception
|
||||||
def render_POST(self, req):
|
def render_POST(self, req):
|
||||||
"""
|
"""
|
||||||
"POST /uri?t=upload&file=newfile" to upload an
|
"POST /uri?t=upload&file=newfile" to upload an
|
||||||
@ -135,6 +140,7 @@ class URIHandler(resource.Resource, object):
|
|||||||
"and POST?t=mkdir")
|
"and POST?t=mkdir")
|
||||||
raise WebError(errmsg, http.BAD_REQUEST)
|
raise WebError(errmsg, http.BAD_REQUEST)
|
||||||
|
|
||||||
|
@exception_to_child
|
||||||
def getChild(self, name, req):
|
def getChild(self, name, req):
|
||||||
"""
|
"""
|
||||||
Most requests look like /uri/<cap> so this fetches the capability
|
Most requests look like /uri/<cap> so this fetches the capability
|
||||||
@ -167,6 +173,7 @@ class FileHandler(resource.Resource, object):
|
|||||||
super(FileHandler, self).__init__()
|
super(FileHandler, self).__init__()
|
||||||
self.client = client
|
self.client = client
|
||||||
|
|
||||||
|
@exception_to_child
|
||||||
def getChild(self, name, req):
|
def getChild(self, name, req):
|
||||||
if req.method not in ("GET", "HEAD"):
|
if req.method not in ("GET", "HEAD"):
|
||||||
raise WebError("/file can only be used with GET or HEAD")
|
raise WebError("/file can only be used with GET or HEAD")
|
||||||
@ -181,6 +188,7 @@ class FileHandler(resource.Resource, object):
|
|||||||
raise WebError("'%s' is not a file-cap" % name)
|
raise WebError("'%s' is not a file-cap" % name)
|
||||||
return filenode.FileNodeDownloadHandler(self.client, node)
|
return filenode.FileNodeDownloadHandler(self.client, node)
|
||||||
|
|
||||||
|
@render_exception
|
||||||
def render_GET(self, ctx):
|
def render_GET(self, ctx):
|
||||||
raise WebError("/file must be followed by a file-cap and a name",
|
raise WebError("/file must be followed by a file-cap and a name",
|
||||||
http.NOT_FOUND)
|
http.NOT_FOUND)
|
||||||
@ -188,6 +196,7 @@ class FileHandler(resource.Resource, object):
|
|||||||
class IncidentReporter(MultiFormatResource):
|
class IncidentReporter(MultiFormatResource):
|
||||||
"""Handler for /report_incident POST request"""
|
"""Handler for /report_incident POST request"""
|
||||||
|
|
||||||
|
@render_exception
|
||||||
def render(self, req):
|
def render(self, req):
|
||||||
if req.method != "POST":
|
if req.method != "POST":
|
||||||
raise WebError("/report_incident can only be used with POST")
|
raise WebError("/report_incident can only be used with POST")
|
||||||
@ -236,6 +245,7 @@ class Root(MultiFormatResource):
|
|||||||
|
|
||||||
self.putChild("report_incident", IncidentReporter())
|
self.putChild("report_incident", IncidentReporter())
|
||||||
|
|
||||||
|
@exception_to_child
|
||||||
def getChild(self, path, request):
|
def getChild(self, path, request):
|
||||||
if not path:
|
if not path:
|
||||||
# Render "/" path.
|
# Render "/" path.
|
||||||
@ -254,9 +264,11 @@ class Root(MultiFormatResource):
|
|||||||
storage_server = None
|
storage_server = None
|
||||||
return storage.StorageStatus(storage_server, self._client.nickname)
|
return storage.StorageStatus(storage_server, self._client.nickname)
|
||||||
|
|
||||||
|
@render_exception
|
||||||
def render_HTML(self, req):
|
def render_HTML(self, req):
|
||||||
return renderElement(req, RootElement(self._client, self._now_fn))
|
return renderElement(req, RootElement(self._client, self._now_fn))
|
||||||
|
|
||||||
|
@render_exception
|
||||||
def render_JSON(self, req):
|
def render_JSON(self, req):
|
||||||
req.setHeader("content-type", "application/json; charset=utf-8")
|
req.setHeader("content-type", "application/json; charset=utf-8")
|
||||||
intro_summaries = [s.summary for s in self._client.introducer_connection_statuses()]
|
intro_summaries = [s.summary for s in self._client.introducer_connection_statuses()]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user