def locateChild(self, ctx, segments): from knoboo.external.twisted.web2.server import parsePOSTData request = iweb.IRequest(ctx) if request.method == "POST": return parsePOSTData(request).addCallback( lambda x: self.__original.locateChild(ctx, segments)) return self.__original.locateChild(ctx, segments)
def locateChild(self, request, segments): """Before returning a resource and segments, determine what resource to fetch by checking the following conditions: - (authenticated user) request has cookie with valid session id return users resource tree - (authenticating user) request is a POST with username password credentials and path is 'login' return users resource tree if authenticated, or an anonymous resource tree otherwise - (anonymous user) request may have invalid credentials, or no credentials return an anonymous resource tree """ session = self.getSession(request) if session: if segments[0] == 'logout': self.sessionManager.expireSession(session) return self.anonymousLogin(request, segments) res = session.getResource() return res, segments if segments[0] == 'login': d = server.parsePOSTData(request) d.addCallback(lambda _: self.login(request, segments)) return d #return self.login(request, segments) return self.anonymousLogin(request, segments)
def test_maxFields(self): """ Check that the C{maxSize} parameter makes the parsing raise an exception if the data contains too many fields. """ ctype = http_headers.MimeType("multipart", "form-data", (("boundary", "---xyz"),)) content = """-----xyz\r Content-Disposition: form-data; name="foo"\r \r Foo Bar\r -----xyz\r Content-Disposition: form-data; name="foo"\r \r Baz\r -----xyz\r Content-Disposition: form-data; name="file"; filename="filename"\r Content-Type: text/html\r \r blah\r -----xyz\r Content-Disposition: form-data; name="file"; filename="filename"\r Content-Type: text/plain\r \r bleh\r -----xyz--\r """ root = resource.Resource() request = SimpleRequest(server.Site(root), "GET", "/", http_headers.Headers({"content-type": ctype}), content) def cb(res): self.assertEquals(res.response.description, "Maximum number of fields 3 exceeded") return self.assertFailure(server.parsePOSTData(request, maxFields=3), http.HTTPError).addCallback(cb)
def test_multipart(self): """ Test parsing data in multipart format: it should fill the C{files} attribute. """ ctype = http_headers.MimeType("multipart", "form-data", (("boundary", "---weeboundary"),)) content = """-----weeboundary\r Content-Disposition: form-data; name="FileNameOne"; filename="myfilename"\r Content-Type: text/html\r \r my great content wooo\r -----weeboundary--\r """ root = resource.Resource() request = SimpleRequest(server.Site(root), "GET", "/", http_headers.Headers({"content-type": ctype}), content) def cb(ign): self.assertEquals(request.args, {}) self.assertEquals(request.files.keys(), ["FileNameOne"]) self.assertEquals( request.files.values()[0][0][:2], ("myfilename", http_headers.MimeType("text", "html", {})) ) f = request.files.values()[0][0][2] self.assertEquals(f.read(), "my great content wooo") return server.parsePOSTData(request).addCallback(cb)
def test_wrongContentType(self): """ Check that a content-type not handled raise a C{http.HTTPError}. """ ctype = http_headers.MimeType("application", "foobar") content = "key=value&multiple=two+words&multiple=more%20words" root = resource.Resource() request = SimpleRequest(server.Site(root), "GET", "/", http_headers.Headers({"content-type": ctype}), content) return self.assertFailure(server.parsePOSTData(request), http.HTTPError)
def http_POST(self, request): """ Respond to a POST request. Reads and parses the incoming body data then calls L{render}. @param request: the request to process. @return: an object adaptable to L{iweb.IResponse}. """ return server.parsePOSTData(request, self.maxMem, self.maxFields, self.maxSize ).addCallback(lambda res: self.render(request))
def test_noContentType(self): """ Parsing a request without content-type should succeed but should not fill the C{args} and C{files} attributes of the request. """ root = resource.Resource() request = SimpleRequest(server.Site(root), "GET", "/", content="foo") def cb(ign): self.assertEquals(request.args, {}) self.assertEquals(request.files, {}) return server.parsePOSTData(request).addCallback(cb)
def test_otherErrors(self): """ Test that errors durign parsing other than C{MimeFormatError} are propagated. """ ctype = http_headers.MimeType("multipart", "form-data", (("boundary", "---weeboundary"),)) # XXX: maybe this is not a good example # parseContentDispositionFormData could handle this problem content = """-----weeboundary\r Content-Disposition: form-data; name="FileNameOne"; filename="myfilename and invalid data \r -----weeboundary--\r """ root = resource.Resource() request = SimpleRequest(server.Site(root), "GET", "/", http_headers.Headers({"content-type": ctype}), content) return self.assertFailure(server.parsePOSTData(request), ValueError)
def test_urlencoded(self): """ Test parsing data in urlencoded format: it should end in the C{args} attribute. """ ctype = http_headers.MimeType("application", "x-www-form-urlencoded") content = "key=value&multiple=two+words&multiple=more%20words" root = resource.Resource() request = SimpleRequest(server.Site(root), "GET", "/", http_headers.Headers({"content-type": ctype}), content) def cb(ign): self.assertEquals(request.files, {}) self.assertEquals(request.args, {"multiple": ["two words", "more words"], "key": ["value"]}) return server.parsePOSTData(request).addCallback(cb)
def test_multipartWithNoBoundary(self): """ If the boundary type is not specified, parsing should fail with a C{http.HTTPError}. """ ctype = http_headers.MimeType("multipart", "form-data") content = """-----weeboundary\r Content-Disposition: form-data; name="FileNameOne"; filename="myfilename"\r Content-Type: text/html\r \r my great content wooo\r -----weeboundary--\r """ root = resource.Resource() request = SimpleRequest(server.Site(root), "GET", "/", http_headers.Headers({"content-type": ctype}), content) return self.assertFailure(server.parsePOSTData(request), http.HTTPError)
def test_mimeParsingError(self): """ A malformed content should result in a C{http.HTTPError}. The tested content has an invalid closing boundary. """ ctype = http_headers.MimeType("multipart", "form-data", (("boundary", "---weeboundary"),)) content = """-----weeboundary\r Content-Disposition: form-data; name="FileNameOne"; filename="myfilename"\r Content-Type: text/html\r \r my great content wooo\r -----weeoundary--\r """ root = resource.Resource() request = SimpleRequest(server.Site(root), "GET", "/", http_headers.Headers({"content-type": ctype}), content) return self.assertFailure(server.parsePOSTData(request), http.HTTPError)
def test_multipartMaxSize(self): """ Check that the C{maxSize} parameter makes the parsing raise an exception if the data is too big. """ ctype = http_headers.MimeType("multipart", "form-data", (("boundary", "---weeboundary"),)) content = """-----weeboundary\r Content-Disposition: form-data; name="FileNameOne"; filename="myfilename"\r Content-Type: text/html\r \r my great content wooo and even more and more\r -----weeboundary--\r """ root = resource.Resource() request = SimpleRequest(server.Site(root), "GET", "/", http_headers.Headers({"content-type": ctype}), content) def cb(res): self.assertEquals(res.response.description, "Maximum length of 10 bytes exceeded.") return self.assertFailure(server.parsePOSTData(request, maxSize=10), http.HTTPError).addCallback(cb)
def renderHTTP(self, ctx): from knoboo.external.twisted.web2.server import parsePOSTData request = iweb.IRequest(ctx) if request.method == "POST": return parsePOSTData(request).addCallback(self.__reallyRender, ctx) return self.__reallyRender(None, ctx)