def __init__(self, path, command, channel, response, stdin=None, environ=None, globbing=None, recursive=0, size=None): # we need to store the globbing information to pass it # to the ZPublisher and the manage_FTPlist function # (ajung) self.globbing = globbing self.recursive = recursive if stdin is None: size = 0 stdin = StringIO() if environ is None: environ = self._get_env(path, command, channel, stdin, size) self._orig_env = environ HTTPRequest.__init__(self, stdin, environ, response, clean=1) # support for cookies and cookie authentication self.cookies = channel.cookies if '__ac' not in self.cookies and channel.userid != 'anonymous': self.other['__ac_name'] = channel.userid self.other['__ac_password'] = channel.password for k, v in self.cookies.items(): if k not in self.other: self.other[k] = v
def test_default_viewname_overrides_fti(self): response = HTTPResponse() environment = { 'URL': '', 'PARENTS': [self.site], 'REQUEST_METHOD': 'GET', 'SERVER_PORT': '80', 'REQUEST_METHOD': 'GET', 'steps': [], 'SERVER_NAME': 'localhost', '_hacked_path': 0 } r = HTTPRequest(StringIO(), environment, response) r.other.update(environment) # we define a Zope3-style default view name for which a view # actually exists defineDefaultViewName('index.html', IDummyContent) try: from zope.component import provideAdapter provideAdapter(DummyView, (DummyContent, IBrowserRequest), IBrowserView, 'index.html') except ImportError: # BBB for Zope 2.8 from zope.app.tests import ztapi ztapi.browserView(IDummyContent, 'index.html', DummyView) r.traverse('foo') self.assertEqual( r.URL, '/foo/index.html' ) self.assertEqual( r.response.base, '/foo/' )
def test_update_preserves_mimetype(self): self.folder.invokeFactory('DDocument', 'mydoc', title="My Doc") doc = self.folder.mydoc doc.setBody(""" An rst Document =============== * Which * has * some * bullet:: points. * for testing""", mimetype="text/restructured") doc.reindexObject() mimetype = doc.getField('body').getContentType(doc) self.assertEqual(mimetype, 'text/x-rst') # update schema for all DDocuments and check if our type is preserved request = HTTPRequest(sys.stdin, {'SERVER_NAME': 'test', 'SERVER_PORT': '8080'}, {}) request.form['Archetypes.DDocument'] = True request.form['update_all'] = True self.portal.archetype_tool.manage_updateSchema(REQUEST=request) doc = self.folder.mydoc mimetype = doc.getField('body').getContentType(doc) self.assertEqual(mimetype, 'text/x-rst')
def addRequestContainer(app, environ=None): """Add the request container with a fake request to the app object's acquisition context and return the wrapped app object. Additional request environment values can be passed as a dict ``environ``. """ from sys import stdin, stdout from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPResponse import HTTPResponse from ZPublisher.BaseRequest import RequestContainer from zope.publisher.browser import setDefaultSkin if environ is None: environ = {} environ.setdefault('SERVER_NAME', 'nohost') environ.setdefault('SERVER_PORT', 'port') environ.setdefault('REQUEST_METHOD', 'GET') resp = HTTPResponse(stdout=stdout) req = HTTPRequest(stdin, environ, resp) req._steps = ['noobject'] # Fake a published object. setDefaultSkin(req) requestcontainer = RequestContainer(REQUEST=req) return app.__of__(requestcontainer)
def _executeAsUser(context_path, portal_path, uf_path, user_id, func, *args, **kwargs): """Reconstruct environment and execute func.""" transaction = Zope2.zpublisher_transactions_manager # Supports isDoomed transaction.begin() app = Zope2.app() result = None try: try: portal = app.unrestrictedTraverse(portal_path, None) if portal is None: raise BadRequest( 'Portal path %s not found' % '/'.join(portal_path)) setSite(portal) if uf_path: acl_users = app.unrestrictedTraverse(uf_path, None) if acl_users is None: raise BadRequest( 'Userfolder path %s not found' % '/'.join(uf_path)) user = acl_users.getUserById(user_id) if user is None: raise BadRequest('User %s not found' % user_id) newSecurityManager(None, user) context = portal.unrestrictedTraverse(context_path, None) if context is None: raise BadRequest( 'Context path %s not found' % '/'.join(context_path)) # Create a request to work with import sys from ZPublisher.HTTPResponse import HTTPResponse from ZPublisher.HTTPRequest import HTTPRequest response = HTTPResponse(stdout=sys.stdout) env = {'SERVER_NAME':'fake_server', 'SERVER_PORT':'80', 'REQUEST_METHOD':'GET'} request = HTTPRequest(sys.stdin, env, response) # Set values from original request original_request = kwargs.get('original_request') if original_request: for k,v in original_request.items(): request.set(k, v) context.REQUEST = request result = func(context, *args, **kwargs) del context.REQUEST #Avoid "can't pickle file objects" transaction.commit() except: transaction.abort() raise finally: noSecurityManager() setSite(None) app._p_jar.close() return result
def decodeQueryString(QueryString): """decode *QueryString* into a dictionary, as ZPublisher would do""" r= HTTPRequest(None, {'QUERY_STRING' : QueryString, 'SERVER_URL' : '', }, None,1) r.processInputs() return r.form
def __init__(self,language=None): resp = HTTPResponse(stdout=sys.stdout) environ={} environ['SERVER_NAME']='foo' environ['SERVER_PORT']='80' environ['REQUEST_METHOD'] = 'GET' environ['SCRIPT_NAME']='/foo/test' environ['SESSION']=None self.SESSION={} HTTPRequest.__init__(self,None,environ,resp) if language: self.setLanguage(language)
def _make_request(self): environ = {} environ['SERVER_NAME'] = 'foo' environ['SERVER_PORT'] = '80' environ['REQUEST_METHOD'] = 'GET' resp = HTTPResponse(stdout=sys.stdout) req = HTTPRequest(stdin=file, environ=environ, response=resp) session = SessionMock() req.other['SESSION'] = session req['ACTUAL_URL'] = 'http://nohost/' return req
def FakeRequest(method='GET', add_auth=False, **kwargs): environ = {} environ.setdefault('SERVER_NAME', 'foo') environ.setdefault('SERVER_PORT', '80') environ.setdefault('REQUEST_METHOD', method) request = HTTPRequest(sys.stdin, environ, HTTPResponse(stdout=StringIO())) request.form = kwargs if add_auth: request.form['_authenticator'] = plone.protect.createToken() return request
def testRequest(): """Create a new request object. This is based on the code in :py:func`Testing.makerequest.makerequest`.""" import sys from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPResponse import HTTPResponse environ = {"SERVER_NAME": "localhost", "SERVER_PORT": "80", "REQUEST_METHOD": "GET"} request = HTTPRequest(sys.stdin, environ, HTTPResponse()) request._steps = ["Plone"] return request
def test_Language_with_header(self): from plone.app.caching.operations.etags import Language environ = {'SERVER_NAME': 'example.com', 'SERVER_PORT': '80'} response = HTTPResponse() request = HTTPRequest(StringIO(), environ, response) published = DummyPublished(DummyContext()) request.environ['HTTP_ACCEPT_LANGUAGE'] = 'en' etag = Language(published, request) self.assertEqual('en', etag())
def testRemoveStdinReferences(self): # Verifies that all references to the input stream go away on # request.close(). Otherwise a tempfile may stick around. import sys from StringIO import StringIO s = StringIO(TEST_FILE_DATA) env = TEST_ENVIRON.copy() start_count = sys.getrefcount(s) from ZPublisher.HTTPRequest import HTTPRequest req = HTTPRequest(s, env, None) req.processInputs() self.assertNotEqual(start_count, sys.getrefcount(s)) # Precondition req.close() self.assertEqual(start_count, sys.getrefcount(s)) # The test
def testTrustedProxies(self): TEST_ENVIRON = { 'REQUEST_METHOD': 'GET', 'SERVER_NAME': 'localhost', 'SERVER_PORT': '80', 'REMOTE_ADDR': '127.0.0.1', 'HTTP_X_FORWARDED_FOR': '10.1.20.30, 192.168.1.100', } from StringIO import StringIO from ZPublisher.HTTPRequest import HTTPRequest, trusted_proxies s = StringIO('') env = TEST_ENVIRON.copy() request = HTTPRequest(s, env, None) self.assertEqual(request.getClientAddr(), '127.0.0.1') trusted_proxies.append('127.0.0.1') request = HTTPRequest(s, env, None) self.assertEqual(request.getClientAddr(), '192.168.1.100') trusted_proxies[0] = '192.168.1.100' env = TEST_ENVIRON.copy() env['REMOTE_ADDR'] = '192.168.1.100' request = HTTPRequest(s, env, None) self.assertEqual(request.getClientAddr(), '10.1.20.30') env = TEST_ENVIRON.copy() del env['REMOTE_ADDR'] request = HTTPRequest(s, env, None) self.assertEqual(request.getClientAddr(), '')
def testFileIterator(self): # checks fileupload object supports the iterator protocol # collector entry 1837 import sys from StringIO import StringIO s = StringIO(TEST_FILE_DATA) env = TEST_ENVIRON.copy() from ZPublisher.HTTPRequest import HTTPRequest req = HTTPRequest(s, env, None) req.processInputs() f=req.form.get('file') self.assertEqual(list(f),['test\n']) f.seek(0) self.assertEqual(f.next(),'test\n') f.seek(0) self.assertEqual(f.xreadlines(),f)
def makerequest(app, stdout=stdout): resp = HTTPResponse(stdout=stdout) environ = os.environ.copy() environ['SERVER_NAME'] = 'foo' environ['SERVER_PORT'] = '80' environ['REQUEST_METHOD'] = 'GET' req = HTTPRequest(stdin, environ, resp) req._steps = ['noobject'] # Fake a published object. req['ACTUAL_URL'] = req.get('URL') # Zope 2.7.4 # set Zope3-style default skin so that the request is usable for # Zope3-style view look-ups. from zope.app.publication.browser import setDefaultSkin setDefaultSkin(req) requestcontainer = RequestContainer(REQUEST = req) return app.__of__(requestcontainer)
def test_default_view_from_fti(self): response = HTTPResponse() environment = { 'URL': '', 'PARENTS': [self.site], 'REQUEST_METHOD': 'GET', 'SERVER_NAME': 'localhost', 'SERVER_PORT': '80', 'REQUEST_METHOD': 'GET', 'steps': [], '_hacked_path': 0} r = HTTPRequest(StringIO(), environment, response) r.other.update(environment) r.traverse('foo') self.assertEqual( r.URL, '/foo/dummy_view' ) self.assertEqual( r.response.base, '/foo/', 'CMF Collector issue #192 (wrong base): %s' % (r.response.base or 'empty',) )
def makerequest(app, stdout=None, environ=None): """ Adds an HTTPRequest at app.REQUEST, and returns app.__of__(app.REQUEST). Useful for tests that need to acquire REQUEST. Usage: import makerequest app = makerequest.makerequest(app) You should only wrap the object used as 'root' in your tests. app is commonly a Zope2.app(), but that's not strictly necessary and frequently may be overkill; you can wrap other objects as long as they support acquisition and provide enough of the features of Zope2.app for your tests to run. For example, if you want to call getPhysicalPath() on child objects, app must provide a non-recursive implementation of getPhysicalPath(). *stdout* is an optional file-like object and is used by REQUEST.RESPONSE. The default is sys.stdout. *environ* is an optional mapping to be used in the request. Default is a fresh dictionary. Passing os.environ is not recommended; tests should not pollute the real os.environ. """ if stdout is None: stdout = BytesIO() if environ is None: environ = {} resp = HTTPResponse(stdout=stdout) environ.setdefault('SERVER_NAME', 'nohost') environ.setdefault('SERVER_PORT', '80') environ.setdefault('REQUEST_METHOD', 'GET') req = HTTPRequest(BytesIO(), environ, resp) req._steps = ['noobject'] # Fake a published object. req['ACTUAL_URL'] = req.get('URL') # Zope 2.7.4 # Set default skin so that the request is usable for view look-ups. from zope.publisher.browser import setDefaultSkin setDefaultSkin(req) requestcontainer = RequestContainer(REQUEST=req) return app.__of__(requestcontainer)
def test_default_viewname_but_no_view_doesnt_override_fti(self): response = HTTPResponse() environment = { 'URL': '', 'PARENTS': [self.site], 'REQUEST_METHOD': 'GET', 'SERVER_NAME': 'localhost', 'SERVER_PORT': '80', 'REQUEST_METHOD': 'GET', 'steps': [], '_hacked_path': 0 } r = HTTPRequest(StringIO(), environment, response) r.other.update(environment) # we define a Zope3-style default view name, but no # corresponding view, no change in behaviour expected defineDefaultViewName('index.html', IDummyContent) r.traverse('foo') self.assertEqual( r.URL, '/foo/dummy_view' ) self.assertEqual( r.response.base, '/foo/' )
def test_GZip_enabled(self): from plone.app.caching.operations.etags import GZip provideUtility(Registry(), IRegistry) registry = getUtility(IRegistry) registry.registerInterface(IPloneCacheSettings) ploneSettings = registry.forInterface(IPloneCacheSettings) ploneSettings.enableCompression = True environ = {'SERVER_NAME': 'example.com', 'SERVER_PORT': '80'} response = HTTPResponse() request = HTTPRequest(StringIO(), environ, response) published = DummyPublished(DummyContext()) request.environ['HTTP_ACCEPT_ENCODING'] = 'deflate; gzip' etag = GZip(published, request) self.assertEqual('1', etag())
def makeTestRequest(environ=None): """Return an HTTPRequest object suitable for testing views.""" from sys import stdin, stdout from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPResponse import HTTPResponse from zope.publisher.browser import setDefaultSkin if environ is None: environ = {} environ.setdefault('SERVER_NAME', 'foo') environ.setdefault('SERVER_PORT', '80') environ.setdefault('REQUEST_METHOD', 'GET') resp = HTTPResponse(stdout=stdout) req = HTTPRequest(stdin, environ, resp) req._steps = ['noobject'] # Fake a published object. req['ACTUAL_URL'] = req.get('URL') setDefaultSkin(req) return req
def makerequest(environ=None, stdin=''): stdout = StringIO() stdin = StringIO(stdin) if environ is None: environ = {} # Header-Name -> HEADER_NAME _ = {} for k,v in environ.items(): k = k.replace('-', '_').upper() _[k] = v environ = _ response = HTTPResponse(stdout=stdout) environ.setdefault('SERVER_NAME', 'foo') environ.setdefault('SERVER_PORT', '80') request = HTTPRequest(stdin, environ, response) # process stdin data request.processInputs() return request
def new_processInputs(self): HTTPRequest.old_processInputs(self) request = self # Set the AcceptLanguage variable # Initialize with the browser configuration accept_language = request['HTTP_ACCEPT_LANGUAGE'] # Patches for user agents that don't support correctly the protocol user_agent = request['HTTP_USER_AGENT'] if user_agent.startswith('Mozilla/4') and user_agent.find('MSIE') == -1: # Netscape 4.x q = 1.0 langs = [] for lang in [x.strip() for x in accept_language.split(',')]: langs.append('%s;q=%f' % (lang, q)) q = q / 2 accept_language = ','.join(langs) accept_language = AcceptLanguageType.decode(accept_language) self.other['AcceptLanguage'] = accept_language
def new_processInputs(self): HTTPRequest.old_processInputs(self) request = self # Set the AcceptLanguage variable # Initialize with the browser configuration accept_language = request['HTTP_ACCEPT_LANGUAGE'] # Patches for user agents that don't support correctly the protocol user_agent = request['HTTP_USER_AGENT'] if user_agent.startswith('Mozilla/4') and user_agent.find('MSIE') == -1: # Netscape 4.x q = 1.0 langs = [] for lang in [ x.strip() for x in accept_language.split(',') ]: langs.append('%s;q=%f' % (lang, q)) q = q/2 accept_language = ','.join(langs) accept_language = AcceptLanguageType.decode(accept_language) self.other['AcceptLanguage'] = accept_language
def makerequest(root, stdout, stdin=None): # Customized version of Testing.makerequest.makerequest() resp = HTTPResponse(stdout=stdout) environ = {} environ['SERVER_NAME'] = 'example.com' environ['SERVER_PORT'] = '80' environ['REQUEST_METHOD'] = 'GET' if stdin is None: stdin = StringIO('') # Empty input req = HTTPRequest(stdin, environ, resp) req['PARENTS'] = [root] return req
def test_default_view_from_fti(self): response = HTTPResponse() environment = { 'URL': '', 'PARENTS': [self.site], 'REQUEST_METHOD': 'GET', 'SERVER_NAME': 'localhost', 'SERVER_PORT': '80', 'REQUEST_METHOD': 'GET', 'steps': [], '_hacked_path': 0 } r = HTTPRequest(StringIO(), environment, response) r.other.update(environment) r.traverse('foo') self.assertEqual(r.URL, '/foo/dummy_view') self.assertEqual( r.response.base, '/foo/', 'CMF Collector issue #192 (wrong base): %s' % (r.response.base or 'empty', ))
def makeRequestAndResponse(): # the POST checking requires a real HTTPRequest from six import StringIO from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPResponse import HTTPResponse res = HTTPResponse() req = HTTPRequest(StringIO(), { 'SERVER_NAME': 'localhost', 'SERVER_PORT': '80' }, res) return req, res
def getContext(self, app): from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPResponse import HTTPResponse from ZPublisher.BaseRequest import RequestContainer resp = HTTPResponse(stdout=None) env = { 'SERVER_NAME':'localhost', 'SERVER_PORT':'8080', 'REQUEST_METHOD':'GET' } req = HTTPRequest(None, env, resp) return app.__of__(RequestContainer(REQUEST = req))
def test_default_viewname_but_no_view_doesnt_override_fti(self): response = HTTPResponse() environment = { 'URL': '', 'PARENTS': [self.site], 'REQUEST_METHOD': 'GET', 'SERVER_NAME': 'localhost', 'SERVER_PORT': '80', 'REQUEST_METHOD': 'GET', 'steps': [], '_hacked_path': 0 } r = HTTPRequest(StringIO(), environment, response) r.other.update(environment) # we define a Zope3-style default view name, but no # corresponding view, no change in behaviour expected defineDefaultViewName('index.html', IDummyContent) r.traverse('foo') self.assertEqual(r.URL, '/foo/dummy_view') self.assertEqual(r.response.base, '/foo/')
def testCSRF(self): """ test csrf protection """ # for this test, we need a bit more serious request simulation from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPResponse import HTTPResponse environ = {} environ.setdefault("SERVER_NAME", "foo") environ.setdefault("SERVER_PORT", "80") environ.setdefault("REQUEST_METHOD", "POST") request = HTTPRequest(sys.stdin, environ, HTTPResponse(stdout=sys.stdout)) request.form = {"topic": "test subject", "replyto": "*****@*****.**", "comments": "test comments"} self.ff1.checkAuthenticator = True self.assertRaises(zExceptions.Forbidden, self.ff1.fgvalidate, request) # with authenticator... no error tag = AuthenticatorView("context", "request").authenticator() token = tag.split('"')[5] request.form["_authenticator"] = token errors = self.ff1.fgvalidate(REQUEST=request) self.assertEqual(errors, {}) # sneaky GET request environ["REQUEST_METHOD"] = "GET" request = HTTPRequest(sys.stdin, environ, HTTPResponse(stdout=sys.stdout)) self.assertRaises(zExceptions.Forbidden, self.ff1.fgvalidate, request) # bad authenticator request.form["_authenticator"] = "inauthentic" request = HTTPRequest(sys.stdin, environ, HTTPResponse(stdout=sys.stdout)) self.assertRaises(zExceptions.Forbidden, self.ff1.fgvalidate, request)
def _physicalPathToVirtualPath(self, path): """ Remove the path to the VirtualRoot from a physical path and add the path to the WebSite if any """ if isinstance(path, str): path = path.split('/') # Every Web Section acts as a mini site though layout for document editing is the root layout #website_path = self._v_request.get(WEBSECTION_KEY, self._v_request.get(WEBSITE_KEY, None)) # Only consider Web Site for absolute_url request = getattr(self, '_v_request', None) if request is None: request = self._v_request = get_request() # In ignore_layout case, we only remove empty element from path # XXX more support required for ignore_layout? if request.get('ignore_layout', None): return HTTPRequest.physicalPathToVirtualPath(request, path) website_path = request.get(WEBSITE_KEY, None) select_language = request.get(WEBSITE_LANGUAGE_KEY, None) if website_path: website_path = tuple(website_path) # Make sure all path are tuples path = tuple(path) # Make sure all path are tuples if select_language: website_path = website_path + (select_language, ) # Add the language part # Search for the common part index # XXX more testing should be added to check # if the URL is the kind of URL which is a Web Site common_index = 0 i = 0 path_len = len(path) for name in website_path: if i >= path_len: break if path[i] == name: common_index = i i += 1 # Insert the web site path after the common part of the path if path_len > common_index + 1: path = website_path + path[common_index + 1:] rpp = request.other.get('VirtualRootPhysicalPath', ('', )) i = 0 for name in rpp[:len(path)]: if path[i] == name: i = i + 1 else: break #if self._v_request.has_key(DOCUMENT_NAME_KEY): # # Replace the last id of the path with the name which # # was used to lookup the document # path = path[:-1] + (self._v_request[DOCUMENT_NAME_KEY],) return path[i:]
def setUp(self): self.app = Application() self.app.id = 'App' mgr = BrowserIdManager('browser_id_manager') self.app._setObject('browser_id_manager', mgr) self.m = self.app.browser_id_manager resp = HTTPResponse() environ = {} environ['SERVER_NAME'] = 'fred' environ['SERVER_PORT'] = '80' self.req = HTTPRequest(stdin, environ, resp) self.req['TraversalRequestNameStack'] = ['foo', 'bar'] self.app.REQUEST = self.req
def wrap_with_request(app): from StringIO import StringIO from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPResponse import HTTPResponse from Acquisition import Implicit class FakeRootObject(Implicit): pass fake_root = FakeRootObject() fake_root.app = app stdin = StringIO() environ = {"REQUEST_METHOD": "GET", "SERVER_NAME": "nohost", "SERVER_PORT": "80"} request = HTTPRequest(stdin, environ, HTTPResponse(), clean=1) anonymous_user = fake_root.app.acl_users._nobody request.AUTHENTICATED_USER = anonymous_user fake_root.REQUEST = request return fake_root
def test_disabled(self): provideUtility(Registry(), IRegistry) registry = getUtility(IRegistry) registry.registerInterface(IPloneCacheSettings) environ = {'SERVER_NAME': 'example.com', 'SERVER_PORT': '80'} response = HTTPResponse() request = HTTPRequest(StringIO(), environ, response) published = DummyPublished() GZipTransform(published, request).transformUnicode(u"", "utf-8") self.assertEqual(0, response.enableHTTPCompression(query=True))
def afterSetUp(self): environ = {"SERVER_NAME": "", "SERVER_PORT": "0"} response = HTTPResponse(stdout=BytesIO()) request = HTTPRequest(BytesIO(), environ, response) self.varname = "tree-expansion" # emulate a cookie tree_expansion = ":".join(expanded_nodes).encode("utf-8") request.other[self.varname] = b2a(zlib.compress(tree_expansion)) self.request = request self.items = {} self.root_obj = make_item_from_tuple(tree, self.items) self.tree = ZopeTree(self.root_obj, "id", "children", request, self.varname)
def clone(self): # This method is a dumb copy of Zope-2.8's one that makes timerserver # works in Zope-2.12 too. # # Return a clone of the current request object # that may be used to perform object traversal. environ = self.environ.copy() environ['REQUEST_METHOD'] = 'GET' if self._auth: environ['HTTP_AUTHORIZATION'] = self._auth clone = HTTPRequest(None, environ, HTTPResponse(), clean=1) clone['PARENTS'] = [self['PARENTS'][-1]] return clone
def clean_shutdown_control(self, _shutdown_phase, time_in_this_phase): """ Inform invoked method that a shutdown is in progress. Here we: - Prevent regular tics from being sent. This does not prevent already-issued tics from running. - Issue a special tic, ran asynchronously from regular tics and asynchronously from this thread. - Wait for that special tic to return, so that we know all clean shutdown handlers have completely run. - Return control to caller. To wait for shutdown handler to return, it has been chosen to use a semaphore scheme. It has the following drawbacks: - It is intrusive: we need to hook foreign classes, since it's not the way things happen with regular zope data exchange. - We can't get what the shutdown handler returned (http return code, page content, ...) so we will never take Lifetime's veto. So shutdown handler must block until shutdown is complete, which is not how clean_shutdown_control is supposed to work. Note though that it is a design weakness in clean_shutdown_control, since some shutdown handlers might not have finshed their job at the time process gets closed. """ self.running = False if self.shutdown_method is not None: # XXX: should use a float for time representation method = '%s?phase:int=%i&time_in_phase:float=%f' % \ (self.shutdown_method, _shutdown_phase, time_in_this_phase) stdin = StringIO.StringIO() request_string = 'GET %s HTTP/1.0' % (method, ) request = http_request(DummyChannel(self), request_string, 'GET', method, '1.0', self.headers) environment = self.get_env(request) response = make_response(request, environment) # Hook response._finish to get a notification when request is over. def _finish(): response.__class__._finish(response) wait_for_close_lock.release() response._finish = _finish # (end of hook) zope_request = HTTPRequest(stdin, environment, response) wait_for_close_lock.acquire() self.zhandler('Zope2', zope_request, response) self.log_info('ClockServer: Waiting for shutdown handler.') wait_for_close_lock.acquire() self.log_info('ClockServer: Going on.') wait_for_close_lock.release() return 0 # TODO: detect an error to allow taking the veto.
def _physicalPathToVirtualPath(self, path): """ Remove the path to the VirtualRoot from a physical path and add the path to the WebSite if any """ if isinstance(path, str): path = path.split( '/') # Every Web Section acts as a mini site though layout for document editing is the root layout #website_path = self._v_request.get(WEBSECTION_KEY, self._v_request.get(WEBSITE_KEY, None)) # Only consider Web Site for absolute_url request = getattr(self, '_v_request', None) if request is None: request = self._v_request = get_request() # In ignore_layout case, we only remove empty element from path # XXX more support required for ignore_layout? if request.get('ignore_layout', None): return HTTPRequest.physicalPathToVirtualPath(request, path) website_path = request.get(WEBSITE_KEY, None) select_language = request.get(WEBSITE_LANGUAGE_KEY, None) if website_path: website_path = tuple(website_path) # Make sure all path are tuples path = tuple(path) # Make sure all path are tuples if select_language: website_path = website_path + (select_language,) # Add the language part # Search for the common part index # XXX more testing should be added to check # if the URL is the kind of URL which is a Web Site common_index = 0 i = 0 path_len = len(path) for name in website_path: if i >= path_len: break if path[i] == name: common_index = i i += 1 # Insert the web site path after the common part of the path if path_len > common_index + 1: path = website_path + path[common_index + 1:] rpp = request.other.get('VirtualRootPhysicalPath', ('', )) i = 0 for name in rpp[:len(path)]: if path[i] == name: i = i + 1 else: break #if self._v_request.has_key(DOCUMENT_NAME_KEY): # # Replace the last id of the path with the name which # # was used to lookup the document # path = path[:-1] + (self._v_request[DOCUMENT_NAME_KEY],) return path[i:]
def testCSRF(self): """ test csrf protection """ # for this test, we need a bit more serious request simulation from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPResponse import HTTPResponse environ = {} environ.setdefault('SERVER_NAME', 'foo') environ.setdefault('SERVER_PORT', '80') environ.setdefault('REQUEST_METHOD', 'POST') request = HTTPRequest(sys.stdin, environ, HTTPResponse(stdout=sys.stdout)) request.form = \ {'topic':'test subject', 'replyto':'*****@*****.**', 'comments':'test comments'} self.ff1.checkAuthenticator = True self.assertRaises(zExceptions.Forbidden, self.ff1.fgvalidate, request) # with authenticator... no error tag = AuthenticatorView('context', 'request').authenticator() token = tag.split('"')[5] request.form['_authenticator'] = token errors = self.ff1.fgvalidate(REQUEST=request) self.assertEqual( errors, {} ) # sneaky GET request environ['REQUEST_METHOD'] = 'GET' request = HTTPRequest(sys.stdin, environ, HTTPResponse(stdout=sys.stdout)) self.assertRaises(zExceptions.Forbidden, self.ff1.fgvalidate, request) # bad authenticator request.form['_authenticator'] = 'inauthentic' request = HTTPRequest(sys.stdin, environ, HTTPResponse(stdout=sys.stdout)) self.assertRaises(zExceptions.Forbidden, self.ff1.fgvalidate, request)
def call(self, method, args=(), errorValue=ERROR_MARKER): path = self.servicePath[:] + [method] response = Response() env = {'SERVER_NAME': 'dummy', 'SERVER_PORT': '8080', 'PATH_INFO': '/' + '/'.join(path)} request = HTTPRequest(None, env, response) request.args = args conn = self.db.open() result = '' try: try: root = conn.root() request['PARENTS'] = [root['Application']] ZPublisher.Publish.publish(request, 'Zope2', [None]) result = request.response.body except NotFound, error: log.warning('NotFound when traversing to %s' % '/'.join(path)) except Exception, error: # This thread should never crash, thus a blank except log.error('Processor: ``%s()`` caused an error!' % method) log.exception(error) result = errorValue is ERROR_MARKER and error or errorValue
def test_request(): """ make request suitable for browser views and Zope2 security. """ response = HTTPResponse(stdout=sys.stdout) request = HTTPRequest(sys.stdin, { 'SERVER_NAME': 'localhost', 'SERVER_PORT': '80', 'REQUEST_METHOD': 'GET', }, response) request['ACTUAL_URL'] = 'http://nohost/plone/myform' setDefaultSkin(request) alsoProvides(request, IFormLayer) # suitable for testing z3c.form views return request
def testIfModSince(self): now = time.time() e = {'SERVER_NAME':'foo', 'SERVER_PORT':'80', 'REQUEST_METHOD':'GET'} # not modified since t_notmod = rfc1123_date(now) e['HTTP_IF_MODIFIED_SINCE'] = t_notmod out = StringIO() resp = HTTPResponse(stdout=out) req = HTTPRequest(sys.stdin, e, resp) data = self.file.index_html(req,resp) self.assertEqual(resp.getStatus(), 304) self.assertEqual(data, '') # modified since t_mod = rfc1123_date(now - 100) e['HTTP_IF_MODIFIED_SINCE'] = t_mod out = StringIO() resp = HTTPResponse(stdout=out) req = HTTPRequest(sys.stdin, e, resp) data = self.file.index_html(req,resp) self.assertEqual(resp.getStatus(), 200) self.assertEqual(data, str(self.file.data))
def test_default_viewname_overrides_fti(self): response = HTTPResponse() environment = { 'URL': '', 'PARENTS': [self.site], 'REQUEST_METHOD': 'GET', 'SERVER_PORT': '80', 'REQUEST_METHOD': 'GET', 'steps': [], 'SERVER_NAME': 'localhost', '_hacked_path': 0 } r = HTTPRequest(StringIO(), environment, response) r.other.update(environment) # we define a Zope3-style default view name for which a view # actually exists defineDefaultViewName('index.html', DummyContent) zope.component.provideAdapter( DummyView, (DummyContent, IBrowserRequest), IBrowserView, 'index.html') r.traverse('foo') self.assertEqual( r.URL, '/foo/index.html' ) self.assertEqual( r.response.base, '/foo/' )
def makeRequest(self, path='/', **kw): # create fake request and response for convenience from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPResponse import HTTPResponse stdin = StringIO() stdout = StringIO() # minimal environment needed env = dict(SERVER_NAME='localhost', SERVER_PORT='80', REQUEST_METHOD='GET', SCRIPT_NAME=path) response = HTTPResponse(stdout=stdout) request = HTTPRequest(stdin, env, response) self.requests.append(request) return request
def make_request_response(environ=None): from StringIO import StringIO from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPResponse import HTTPResponse if environ is None: environ = {} stdout = StringIO() stdin = StringIO() resp = HTTPResponse(stdout=stdout) environ.setdefault('SERVER_NAME', 'foo') environ.setdefault('SERVER_PORT', '80') environ.setdefault('REQUEST_METHOD', 'GET') req = HTTPRequest(stdin, environ, resp) return req, resp
def get_dmd(): """Retrieve the DMD object.""" connections = transaction.get()._synchronizers.data.values()[:] connections.reverse() # Make sure we don't get the temporary connection for cxn in connections: db = getattr(cxn, '_db', None) if db and db.database_name != 'temporary': resp = HTTPResponse(stdout=None) env = { 'SERVER_NAME': 'localhost', 'SERVER_PORT': '8080', 'REQUEST_METHOD': 'GET', } req = HTTPRequest(None, env, resp) app = cxn.root()['Application'] app = app.__of__(RequestContainer(REQUEST=req)) return app.zport.dmd
def make_request(): """ make request suitable for browser views and Zope2 security. """ response = HTTPResponse(stdout=sys.stdout) request = HTTPRequest( sys.stdin, { 'SERVER_NAME': 'localhost', 'SERVER_PORT': '80', 'REQUEST_METHOD': 'GET', }, response, ) setDefaultSkin(request) alsoProvides(request, IFormLayer) # suitable for testing z3c.form views alsoProvides(request, ITeamworkProductLayer) # product layer return request
def do_fake_request(self, request_method, headers={}): __version__ = "0.1" env = {} env['SERVER_NAME'] = 'bobo.server' env['SERVER_PORT'] = '80' env['REQUEST_METHOD'] = request_method env['REMOTE_ADDR'] = '204.183.226.81 ' env['REMOTE_HOST'] = 'bobo.remote.host' env['HTTP_USER_AGENT'] = 'Bobo/%s' % __version__ env['HTTP_HOST'] = '127.0.0.1' env['SERVER_SOFTWARE'] = 'Bobo/%s' % __version__ env['SERVER_PROTOCOL'] = 'HTTP/1.0 ' env['HTTP_ACCEPT'] = 'image/gif, image/x-xbitmap, image/jpeg, */* ' env['SERVER_HOSTNAME'] = 'bobo.server.host' env['GATEWAY_INTERFACE'] = 'CGI/1.1 ' env['SCRIPT_NAME'] = 'Main' env.update(headers) return HTTPRequest(StringIO.StringIO(), env, HTTPResponse())
def continue_request(self, sin, request): "continue handling request now that we have the stdin" s = get_header(CONTENT_LENGTH, request.header) if s: s = int(s) else: s = 0 DebugLogger.log('I', id(request), s) env = self.get_environment(request) zresponse = make_response(request, env) if self._force_connection_close: zresponse._http_connection = 'close' zrequest = HTTPRequest(sin, env, zresponse) request.channel.current_request = None request.channel.queue.append((self.module_name, zrequest, zresponse)) request.channel.work()
def makeRequest(self): response = HTTPResponse() request = HTTPRequest(StringIO(''), test_environ.copy(), response) # Set up request.form, etc. request.processInputs() # Make sure the URLs are set up correctly by faking traversal root = DummyObject() root.john = DummyObject() root.john.mc = DummyObject() root.john.mc.clane = DummyObject() request['PARENTS'] = [root] request.traverse(request['PATH_INFO']) return request
def testDebug(self): TEST_ENVIRON = { 'REQUEST_METHOD': 'GET', 'SERVER_NAME': 'localhost', 'SERVER_PORT': '80', } from StringIO import StringIO from ZPublisher.HTTPRequest import HTTPRequest s = StringIO('') # accessing request.debug from non-Zope3 code will raise an # AttributeError env = TEST_ENVIRON.copy() request = HTTPRequest(s, env, None) request.processInputs() self.assertRaises(AttributeError, getattr, request, 'debug') # or it will actually yield a 'debug' form variable if it # exists env = TEST_ENVIRON.copy() env['QUERY_STRING'] = 'debug=1' request = HTTPRequest(s, env, None) request.processInputs() self.assertEqual(request.debug, '1') # if we access request.debug from a Zope 3 package, however, # we will see the DebugFlags instance def getDebug(request): return request.debug # make a forged copy of getDebug that looks as if its module # was a Zope 3 package z3globals = globals().copy() z3globals['__name__'] = 'zope.apackage' import new getDebugFromZope3 = new.function(getDebug.func_code, z3globals) from zope.publisher.base import DebugFlags self.assertEqual(getDebug(request), '1') self.assert_(isinstance(getDebugFromZope3(request), DebugFlags))
def test_Skin_default(self): from plone.app.caching.operations.etags import Skin environ = {'SERVER_NAME': 'example.com', 'SERVER_PORT': '80'} response = HTTPResponse() request = HTTPRequest(StringIO(), environ, response) published = DummyPublished(DummyContext()) class DummyPortalSkins(object): def getRequestVarname(self): return 'skin_name' def getDefaultSkin(self): return 'defaultskin' published.__parent__.portal_skins = DummyPortalSkins() etag = Skin(published, request) self.assertEqual('defaultskin', etag())
def test_cookie(self): """Test cookies""" # by default, the tree sets a cookie, so test for that request = self.request response = request.RESPONSE self.assertTrue(self.varname in response.cookies) # now make a tree that doesn't set a cookie treeexp = response.cookies[self.varname]["value"] environ = {"SERVER_NAME": "", "SERVER_PORT": "0"} response = HTTPResponse(stdout=BytesIO()) request = HTTPRequest(BytesIO(), environ, response) request.other[self.varname] = treeexp self.tree = ZopeTree(self.root_obj, "id", "children", request, self.varname, set_cookie=0) self.assertFalse(self.varname in response.cookies)
def FakeRequest(method="GET", add_auth=False, **kwargs): environ = {} environ.setdefault("SERVER_NAME", "foo") environ.setdefault("SERVER_PORT", "80") environ.setdefault("REQUEST_METHOD", method) if api.env.plone_version() < "5.2": # manually set stdout for Plone < 5.2 request = HTTPRequest(sys.stdin, environ, HTTPResponse(stdout=BytesIO())) else: request = HTTPRequest(sys.stdin, environ, HTTPResponse()) request.form = kwargs if add_auth: request.form["_authenticator"] = plone.protect.createToken() return request
def _getFauxRequest(self, payload, content_type): # environ['method'] = 'POST' # environ['content-disposition'] = disposition # environ['CONTENT_DISPOSITION'] # environ['slug'] = 'The Beach' # environ['charset']= 'utf-8' # environ['BODY'] = payload resp = HTTPResponse(stdout=sys.stdout) environ = {} environ['SERVER_NAME'] = 'foo' environ['SERVER_PORT'] = '80' environ['REQUEST_METHOD'] = 'POST' environ['METHOD'] = 'POST' environ['CONTENT_TYPE'] = content_type environ['CONTENT_LENGTH'] = len(payload) file = StringIO(payload) req = HTTPRequest(stdin=file, environ=environ, response=resp) return req
def testRangeSupport(self): """ functionnal test of range support """ self.loginAsPortalOwner() # Create content content_id = 'test_file' file_content = self.addFileByFileUpload(self.test_folder, content_id) # Get file field file_field = file_content.getField('file') file_content = file_field.get(file_content) # do an simple request e = {'SERVER_NAME':'foo', 'SERVER_PORT':'80', 'REQUEST_METHOD':'GET'} out = StringIO() resp = HTTPResponse(stdout=out) req = HTTPRequest(sys.stdin, e, resp) req.RESPONSE = resp data = file_content.index_html(req, resp) self.failUnless(len(data) == len(file_content) , 'not good lenght data ') # now do an range request with one range e = {'SERVER_NAME':'foo', 'SERVER_PORT':'80', 'REQUEST_METHOD':'GET', 'HTTP_RANGE' : 'bytes=0-10' } resp = HTTPResponse(stdout=out) req = HTTPRequest(sys.stdin, e, resp) req.RESPONSE = resp data = file_content.index_html(req, resp) read_data = '' for d in data: read_data +=d self.failUnless(len(read_data) == 11 , 'not good lenght data <%s>' % len(read_data)) # now mulitple range e = {'SERVER_NAME':'foo', 'SERVER_PORT':'80', 'REQUEST_METHOD':'GET', 'HTTP_RANGE' : 'bytes=0-10, 50-80' } resp = HTTPResponse(stdout=out) req = HTTPRequest(sys.stdin, e, resp) req.RESPONSE = resp data = file_content.index_html(req, resp)
def testUrlBrowserIdIsFound(self): bid = '43295340A0bpcu4nkCI' name = '_ZopeId' resp = HTTPResponse() environ = {} environ['SERVER_NAME'] = 'fred' environ['SERVER_PORT'] = '80' self.req = HTTPRequest(stdin, environ, resp) self.req['TraversalRequestNameStack'] = ['foo', 'bar', bid, name] self.app.REQUEST = self.req self.m.setAutoUrlEncoding(1) self.m.setBrowserIdNamespaces(('url', )) self.m.updateTraversalData() traverser = BrowserIdManagerTraverser() traverser(self.app, self.req) self.failUnless(isAWellFormedBrowserId(self.req.browser_id_)) self.failUnless(self.req.browser_id_ns_ == 'url') self.failUnless(self.req._script[-1] == self.req.browser_id_) self.failUnless(self.req._script[-2] == '_ZopeId') self.failUnless( self.req['TraversalRequestNameStack'] == ['foo', 'bar'])
def testCSRF(self): """ test csrf protection """ # for this test, we need a bit more serious request simulation from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPResponse import HTTPResponse environ = {} environ.setdefault('SERVER_NAME', 'foo') environ.setdefault('SERVER_PORT', '80') environ.setdefault('REQUEST_METHOD', 'POST') request = HTTPRequest(sys.stdin, environ, HTTPResponse(stdout=sys.stdout)) request.form = { 'topic': 'test subject', 'replyto': '*****@*****.**', 'comments': 'test comments', } self.ff1.CSRFProtection = True self.assertRaises(zExceptions.Forbidden, self.ff1.fgvalidate, request) # with authenticator... no error tag = AuthenticatorView('context', 'request').authenticator() token = tag.split('"')[5] request.form['_authenticator'] = token errors = self.ff1.fgvalidate(REQUEST=request) self.assertEqual(errors, {}) # sneaky GET request environ['REQUEST_METHOD'] = 'GET' request = HTTPRequest(sys.stdin, environ, HTTPResponse(stdout=sys.stdout)) self.assertRaises(zExceptions.Forbidden, self.ff1.fgvalidate, request) # bad authenticator request.form['_authenticator'] = 'inauthentic' request = HTTPRequest(sys.stdin, environ, HTTPResponse(stdout=sys.stdout)) self.assertRaises(zExceptions.Forbidden, self.ff1.fgvalidate, request)
def makeFileUpload(data, filename): request_data = upload_request.format(filename, len(data), data) req = HTTPRequest(StringIO(request_data), test_environment.copy(), None) req.processInputs() return req.form.get('file')
def __init__(self, response, interval): stdin=StringIO() environ=self._get_env(stdin) HTTPRequest.__init__(self, stdin, environ, response, clean=1) self.other['interval'] = interval