def fake_nevow_request(method='GET', body=b'', is_secure=False, uri=b'http://example.com/one', request_headers=None, Request=NevowRequest): """ Create a fake `NevowRequest` instance for the purposes of testing. """ uri = URL.from_text(uri.decode('utf-8')).to_uri() channel = DummyChannel() if is_secure: channel.transport = DummyChannel.SSL() request = Request(channel=channel) request.method = method request.uri = url_path(uri) request.clientproto = b'HTTP/1.1' request.client = channel.transport.getPeer() content_length = len(body) request.requestHeaders.setRawHeaders('host', [uri.authority().encode('utf-8')]) request.requestHeaders.setRawHeaders('content-length', [content_length]) if request_headers: for k, v in request_headers.items(): request.requestHeaders.setRawHeaders(k, v) request.gotLength(content_length) request.content.write(body) request.content.seek(0) return request
def _test_censoring(self, path, censored): """ Verify that the event logged for a request for ``path`` does not include ``path`` but instead includes ``censored``. :param bytes path: A request path. :param bytes censored: A replacement value for the request path in the access log. :return: ``None`` if the logging looks good. """ logPath = self.mktemp() site = TahoeLAFSSite(self.mktemp(), Resource(), logPath=logPath) site.startFactory() channel = DummyChannel() channel.factory = site request = TahoeLAFSRequest(channel) request.gotLength(None) request.requestReceived(b"GET", path, b"HTTP/1.1") self.assertThat( FilePath(logPath).getContent(), MatchesAll( Contains(censored), Not(Contains(path)), ), )
def renderResource(self, resource, path): s = appserver.NevowSite(resource) channel = DummyChannel() channel.site = s r = appserver.NevowRequest(channel, True) r.path = path return r.process()
def testChildLink(self): request = server.Request(DummyChannel(), 1) request.gotLength(0) request.requestReceived(b'GET', b'/foo/bar', b'HTTP/1.0') self.assertEqual(request.childLink(b'baz'), b'bar/baz') request = server.Request(DummyChannel(), 1) request.gotLength(0) request.requestReceived(b'GET', b'/foo/bar/', b'HTTP/1.0') self.assertEqual(request.childLink(b'baz'), b'baz')
def testPrePathURLSSLNonDefault(self): d = DummyChannel() d.transport = DummyChannel.SSL() d.transport.port = 81 request = server.Request(d, 1) request.setHost(b'example.com', 81) request.gotLength(0) request.requestReceived(b'GET', b'/foo/bar', b'HTTP/1.0') self.assertEqual(request.prePathURL(), b'https://example.com:81/foo/bar')
def testPrePathURLHTTPPortAndSSL(self): d = DummyChannel() d.transport = DummyChannel.SSL() d.transport.port = 80 request = server.Request(d, 1) request.setHost('example.com', 80) request.gotLength(0) request.requestReceived('GET', '/foo/bar', 'HTTP/1.0') self.assertEqual(request.prePathURL(), 'https://example.com:80/foo/bar')
def create_request(self): channel = DummyChannel() channel.site = PixelatedSite(MagicMock()) request = PixelatedSite.requestFactory(channel=channel, queued=True) request.method = "GET" request.uri = "localhost" request.clientproto = 'HTTP/1.1' request.prepath = [] request.postpath = request.uri.split('/')[1:] request.path = "/" return request
def getTextOfPage(root, page, args=None, return_request=False): """This perpetrates several awful hacks.""" if args is not None: page += '?' + urllib.urlencode(args) channel = DummyChannel() channel.site = Site(root) r = Request(channel, 0) r.content = StringIO() r.requestReceived("GET", "/" + page, "1.1") if return_request: return channel.transport.written.getvalue(), r else: return channel.transport.written.getvalue()
def _create_request(self, tempdir): """ Create and return a new ``TahoeLAFSRequest`` hooked up to a ``TahoeLAFSSite``. :param bytes tempdir: The temporary directory to give to the site. :return TahoeLAFSRequest: The new request instance. """ site = TahoeLAFSSite(tempdir.path, Resource(), logPath=self.mktemp()) site.startFactory() channel = DummyChannel() channel.site = site request = TahoeLAFSRequest(channel) return request
def testPrePathURLSSLPort(self): d = DummyChannel() d.transport.port = 443 request = server.Request(d, 1) request.setHost(b'example.com', 443) request.gotLength(0) request.requestReceived(b'GET', b'/foo/bar', b'HTTP/1.0') self.assertEqual(request.prePathURL(), b'http://example.com:443/foo/bar')
def test_redirectToUnicodeURL(self): """ L{redirectTo} will raise TypeError if unicode object is passed in URL """ request = Request(DummyChannel(), True) request.method = b"GET" targetURL = "http://target.example.com/4321" self.assertRaises(TypeError, redirectTo, targetURL, request)
def test_renderPOST(self): """ A POST request with form data has the form data parsed into C{request.fields}. """ class Res(Render): def renderHTTP(self, ctx): return b'' s = appserver.NevowSite(Res()) channel = DummyChannel() channel.site = s r = appserver.NevowRequest(channel, True) r.method = b'POST' r.path = b'/' r.content = StringIO(b'foo=bar') self.successResultOf(r.process()) self.assertEquals(r.fields[b'foo'].value, b'bar')
def renderResourceReturnTransport(resource, path, method): """ Perform a synthetic request for the given resource. This is like L{renderResource} but with a different return value. @return: All of the bytes written to the transport as a result of the rendering. """ s = appserver.NevowSite(resource) channel = DummyChannel() channel.site = s r = appserver.NevowRequest(channel, True) r.path = path if method is not None: r.method = method d = r.process() d.addCallback(lambda ignored: channel.transport.written.getvalue()) return d
def test_connectionLost(self): """ L{Request.finish} is not called when the connection is lost before rendering has finished. """ rendering = Deferred() class Res(Render): def renderHTTP(self, ctx): return rendering site = appserver.NevowSite(Res()) channel = DummyChannel() channel.site = site request = appserver.NevowRequest(channel, True) request.connectionLost(Exception("Just Testing")) rendering.callback(b"finished") self.assertFalse( request.finished, "Request was incorrectly marked as finished.")
def test_connectionLost(self): """ Ensure that the CGI process ends cleanly when the request connection is lost. """ d = DummyChannel() request = http.Request(d, True) protocol = twcgi.CGIProcessProtocol(request) request.connectionLost(failure.Failure(ConnectionLost("Connection done"))) protocol.processEnded(failure.Failure(error.ProcessTerminated()))
def testUICaching(self): ui_caching = True site = CacheControlledSite(ui_caching, self._resource) request = server.Request(DummyChannel(), False) request.prepath = [b""] request.postpath = [b""] site.getResourceFor(request) self.assertTrue( request.responseHeaders.getRawHeaders("cache-control") == ["max-age={}".format(FRESHNESS_TIME_SECS)])
def testNoUICaching(self): ui_caching = False site = CacheControlledSite(ui_caching, self._resource) request = server.Request(DummyChannel(), False) request.prepath = [b""] request.postpath = [b""] site.getResourceFor(request) self.assertTrue( request.responseHeaders.getRawHeaders("cache-control") == ["no-store, must-revalidate"])
def test_prePathURLQuoting(self): """ L{Request.prePathURL} quotes special characters in the URL segments to preserve the original meaning. """ d = DummyChannel() request = server.Request(d, 1) request.setHost(b'example.com', 80) request.gotLength(0) request.requestReceived(b'GET', b'/foo%2Fbar', b'HTTP/1.0') self.assertEqual(request.prePathURL(), b'http://example.com/foo%2Fbar')
def _getReq(self): """ Generate a dummy request for use by C{_computeAllowedMethod} tests. """ d = DummyChannel() d.site.resource.putChild(b'gettableresource', GettableResource()) d.transport.port = 81 request = server.Request(d, 1) request.setHost(b'example.com', 81) request.gotLength(0) return request
def renderResource(resource, path, method=None): """ Perform a synthetic request for the given resource. @param resource: The L{nevow.inevow.IResource} from which to begin processing. @param path: The path of the url to use in processing. @param method: An optional request method to use. @return: The return value of L{NevowRequest.process} for this resource, path, and method. """ s = appserver.NevowSite(resource) channel = DummyChannel() channel.site = s r = appserver.NevowRequest(channel, True) r.path = path if method is not None: r.method = method return r.process()
def test_write_after_connection_lost(self): """ Calling L{Request.write} after L{Request.connectionLost} has been called should not throw an exception. L{RuntimeError} will be raised when finish is called on the request. NOTE: This test is taken from the upstream fix to verify the monkey patch: https://github.com/twisted/twisted/commit/169fd1d93b7af06bf0f6893b193ce19970881868 """ channel = DummyChannel() req = http.Request(channel, False) req.connectionLost(Failure(ConnectionLost("The end."))) req.write(b"foobar") self.assertRaises(RuntimeError, req.finish)
def _getReq(self, resource=None): """ Create a request object with a stub channel and install the passed resource at /newrender. If no resource is passed, create one. """ d = DummyChannel() if resource is None: resource = NewRenderResource() d.site.resource.putChild(b'newrender', resource) d.transport.port = 81 request = server.Request(d, 1) request.setHost(b'example.com', 81) request.gotLength(0) return request
def test_headersAndCode(self): """ L{redirectTo} will set the C{Location} and C{Content-Type} headers on its request, and set the response code to C{FOUND}, so the browser will be redirected. """ request = Request(DummyChannel(), True) request.method = 'GET' targetURL = "http://target.example.com/4321" redirectTo(targetURL, request) self.assertEqual(request.code, FOUND) self.assertEqual(request.responseHeaders.getRawHeaders('location'), [targetURL]) self.assertEqual(request.responseHeaders.getRawHeaders('content-type'), ['text/html; charset=utf-8'])
def test_requestReceived_converts_extra_slashes_to_single(self): mock_super_requestReceived = self.patch(webapp.Request, "requestReceived") request = webapp.CleanPathRequest(DummyChannel(), sentinel.queued) path_pieces = [ factory.make_name("path").encode("utf-8") for _ in range(3) ] double_path = (b"/" * random.randint(2, 8)).join(path_pieces) single_path = b"/".join(path_pieces) request.requestReceived(sentinel.command, double_path, sentinel.version) self.assertThat( mock_super_requestReceived, MockCalledOnceWith(sentinel.command, single_path, sentinel.version))
def _fields_test(self, method, request_headers, request_body, match_fields): channel = DummyChannel() request = TahoeLAFSRequest(channel, ) for (k, v) in request_headers.items(): request.requestHeaders.setRawHeaders(k, [v]) request.gotLength(len(request_body)) request.handleContentChunk(request_body) request.requestReceived(method, b"/", b"HTTP/1.1") # We don't really care what happened to the request. What we do care # about is what the `fields` attribute is set to. self.assertThat( request.fields, match_fields, )
def renderPage(res, topLevelContext=context.WebContext, reqFactory=FakeRequest): """ Render the given resource. Return a Deferred which fires when it has rendered. """ req = reqFactory() ctx = topLevelContext(tag=res) ctx.remember(req, inevow.IRequest) render = appserver.NevowRequest(DummyChannel(), True).gotPageContext result = render(ctx) result.addCallback(lambda x: req.accumulator) return result
def render(resource, query_args): """ Render (in the manner of the Twisted Web Site) a Twisted ``Resource`` against a request with the given query arguments . :param resource: The page or resource to render. :param query_args: The query arguments to put into the request being rendered. A mapping from ``bytes`` to ``list`` of ``bytes``. :return Deferred: A Deferred that fires with the rendered response body as ``bytes``. """ channel = DummyChannel() request = TahoeLAFSRequest(channel) request.method = b"GET" request.args = query_args request.prepath = [b""] request.postpath = [] try: result = resource.render(request) except UnsupportedMethod: request.setResponseCode(NOT_ALLOWED) result = b"" if isinstance(result, bytes): request.write(result) done = succeed(None) elif result == NOT_DONE_YET: if request.finished: done = succeed(None) else: done = request.notifyFinish() else: raise ValueError( "{!r} returned {!r}, required bytes or NOT_DONE_YET.".format( fullyQualifiedName(resource.render), result, ), ) def get_body(ignored): complete_response = channel.transport.written.getvalue() header, body = complete_response.split(b"\r\n\r\n", 1) return body done.addCallback(get_body) return done
def doLocationTest(self, requestPath: bytes): """ Render a response to a request with path *requestPath* @param requestPath: A slash-separated path like C{b'/foo/bar'}. @returns: The value of the I{Location} header. """ request = Request(DummyChannel(), True) request.method = b"GET" request.prepath = requestPath.lstrip(b"/").split(b"/") resource = ParentRedirect() resource.render(request) [location] = request.responseHeaders.getRawHeaders(b"Location") return location
def test_processingFailedDisplayTraceback(self): """ L{Request.processingFailed} when the site has C{displayTracebacks} set to C{True} writes out the failure. """ d = DummyChannel() request = server.Request(d, 1) request.site = server.Site(resource.Resource()) request.site.displayTracebacks = True fail = failure.Failure(Exception("Oh no!")) request.processingFailed(fail) self.assertIn(b"Oh no!", request._transport.getvalue()) # Since we didn't "handle" the exception, flush it to prevent a test # failure self.assertEqual(1, len(self.flushLoggedErrors()))
def test_processingFailedDisplayTracebackHandlesUnicode(self): """ L{Request.processingFailed} when the site has C{displayTracebacks} set to C{True} writes out the failure, making UTF-8 items into HTML entities. """ d = DummyChannel() request = server.Request(d, 1) request.site = server.Site(resource.Resource()) request.site.displayTracebacks = True fail = failure.Failure(Exception(u"\u2603")) request.processingFailed(fail) self.assertIn(b"☃", request.transport.getvalue()) # Since we didn't "handle" the exception, flush it to prevent a test # failure self.assertEqual(1, len(self.flushLoggedErrors()))
def test_processingFailedNoTraceback(self): """ L{Request.processingFailed} when the site has C{displayTracebacks} set to C{False} does not write out the failure, but give a generic error message. """ d = DummyChannel() request = server.Request(d, 1) request.site = server.Site(resource.Resource()) request.site.displayTracebacks = False fail = failure.Failure(Exception("Oh no!")) request.processingFailed(fail) self.assertNotIn(b"Oh no!", request.transport.getvalue()) self.assertIn(b"Processing Failed", request.transport.getvalue()) # Since we didn't "handle" the exception, flush it to prevent a test # failure self.assertEqual(1, len(self.flushLoggedErrors()))
def createServer(self, r): chan = DummyChannel() chan.site = server.Site(r) return chan