def testFailureConflict(self): r = self.request r.action = 'conflict' publish(r, PUBMODULE, [None]) events = self.reporter.events self.assertEqual(len(events), 7) self.assert_(isinstance(events[0], PubStart)) self.assertEqual(events[0].request, r) self.assert_(isinstance(events[1], PubBeforeAbort)) self.assertEqual(events[1].request, r) self.assertEqual(events[1].retry, True) self.assertEqual(len(events[1].exc_info), 3) self.assert_(isinstance(events[1].exc_info[1], ConflictError)) self.assert_(isinstance(events[2], PubFailure)) self.assertEqual(events[2].request, r) self.assertEqual(events[2].retry, True) self.assertEqual(len(events[2].exc_info), 3) self.assert_(isinstance(events[2].exc_info[1], ConflictError)) self.assert_(isinstance(events[3], PubStart)) self.assert_(isinstance(events[4], PubAfterTraversal)) self.assert_(isinstance(events[5], PubBeforeCommit)) self.assert_(isinstance(events[6], PubSuccess))
def testFailureConflict(self): r = self.request; r.action = 'conflict' publish(r, PUBMODULE, [None]) events = self.reporter.events self.assertEqual(len(events), 7) self.assert_(isinstance(events[0], PubStart)) self.assertEqual(events[0].request, r) self.assert_(isinstance(events[1], PubBeforeAbort)) self.assertEqual(events[1].request, r) self.assertEqual(events[1].retry, True) self.assertEqual(len(events[1].exc_info), 3) self.assert_(isinstance(events[1].exc_info[1], ConflictError)) self.assert_(isinstance(events[2], PubFailure)) self.assertEqual(events[2].request, r) self.assertEqual(events[2].retry, True) self.assertEqual(len(events[2].exc_info), 3) self.assert_(isinstance(events[2].exc_info[1], ConflictError)) self.assert_(isinstance(events[3], PubStart)) self.assert_(isinstance(events[4], PubAfterTraversal)) self.assert_(isinstance(events[5], PubBeforeCommit)) self.assert_(isinstance(events[6], PubSuccess))
def testFailureReturn(self): r = self.request; r.action = 'fail_return' publish(r, PUBMODULE, [None]) events = self.reporter.events self.assertEqual(len(events), 3) self.assert_(isinstance(events[0], PubStart)) self.assertEqual(events[0].request, r) self.assert_(isinstance(events[1], PubBeforeAbort)) self.assertEqual(events[1].request, r) self.assertEqual(events[1].retry, False) self.assert_(isinstance(events[2], PubFailure)) self.assertEqual(events[2].request, r) self.assertEqual(events[2].retry, False) self.assertEqual(len(events[2].exc_info), 3)
def testSuccess(self): r = self.request; r.action = 'succeed' publish(r, PUBMODULE, [None]) events = self.reporter.events self.assertEqual(len(events), 4) self.assert_(isinstance(events[0], PubStart)) self.assertEqual(events[0].request, r) self.assert_(isinstance(events[-1], PubSuccess)) self.assertEqual(events[-1].request, r) # test AfterTraversal and BeforeCommit as well self.assert_(isinstance(events[1], PubAfterTraversal)) self.assertEqual(events[1].request, r) self.assert_(isinstance(events[2], PubBeforeCommit)) self.assertEqual(events[2].request, r)
def wsgi_publish(environ, start_response): """ copied from publish_module in ZPublisher/Test.py, simplified, and modified to accept streaming responses """ from ZPublisher.Request import Request from ZPublisher.Publish import publish from ZServer.HTTPResponse import ZServerHTTPResponse from zope.publisher.browser import setDefaultSkin from StringIO import StringIO outstream = StringIO() must_die=0 after_list=[None] response = ZServerHTTPResponse(stdout=outstream, stderr=sys.stderr) stdout = response.stdout request = Request(environ['wsgi.input'], environ, response) try: try: setDefaultSkin(request) response = publish(request, 'Zope2', after_list, debug=0) except SystemExit, v: must_die=sys.exc_info() response.exception(must_die) except ImportError, v: if isinstance(v, tuple) and len(v)==3: must_die=v else: must_die=sys.exc_info() response.exception(1, v)
def profiled_publish(request, module_name, after_list, debug=0, call_object=call_object, missing_name=missing_name, dont_publish_class=dont_publish_class, mapply=mapply): return publish(request, module_name, after_list, debug, call_object, missing_name, dont_publish_class, mapply)
def profiled_publish( request, module_name, after_list, debug=0, call_object=call_object, missing_name=missing_name, dont_publish_class=dont_publish_class, mapply=mapply): return publish(request, module_name, after_list, debug, call_object, missing_name, dont_publish_class, mapply)
def publish( request, module_name, after_list, debug=0, # Optimize: call_object=call_object, missing_name=missing_name, dont_publish_class=dont_publish_class, mapply=mapply, ): (bobo_before, bobo_after, object, realm, debug_mode, err_hook, validated_hook, transactions_manager) = get_module_info(module_name) parents = None response = None try: with getPublisherDeadlineValue(request): notify(PubStart(request)) # TODO pass request here once BaseRequest implements IParticipation newInteraction() request.processInputs() request_get = request.get response = request.response # First check for "cancel" redirect: if request_get('SUBMIT', '').strip().lower() == 'cancel': cancel = request_get('CANCEL_ACTION', '') if cancel: # Relative URLs aren't part of the spec, but are accepted by # some browsers. for part, base in zip( urlparse(cancel)[:3], urlparse(request['BASE1'])[:3]): if not part: continue if not part.startswith(base): cancel = '' break if cancel: raise Redirect, cancel after_list[0] = bobo_after if debug_mode: response.debug_mode = debug_mode if realm and not request.get('REMOTE_USER', None): response.realm = realm if bobo_before is not None: bobo_before() # Get the path list. # According to RFC1738 a trailing space in the path is valid. path = request_get('PATH_INFO') request['PARENTS'] = parents = [object] if transactions_manager: transactions_manager.begin() object = request.traverse(path, validated_hook=validated_hook) notify(PubAfterTraversal(request)) if transactions_manager: transactions_manager.recordMetaData(object, request) result = mapply(object, request.args, request, call_object, 1, missing_name, dont_publish_class, request, bind=1) if result is not response: response.setBody(result) notify(PubBeforeCommit(request)) if transactions_manager: transactions_manager.commit() endInteraction() notify(PubSuccess(request)) return response except: # save in order to give 'PubFailure' the original exception info exc_info = sys.exc_info() # DM: provide nicer error message for FTP sm = None if response is not None: sm = getattr(response, "setMessage", None) if sm is not None: from asyncore import compact_traceback cl, val = sys.exc_info()[:2] sm('%s: %s %s' % (getattr(cl, '__name__', cl), val, debug_mode and compact_traceback()[-1] or '')) # debug is just used by tests (has nothing to do with debug_mode!) if not debug and err_hook is not None: retry = False if parents: parents = parents[0] try: try: with getPublisherDeadlineValue(request): return err_hook( parents, request, sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2], ) except Retry: if not request.supports_retry(request): with getPublisherDeadlineValue(): return err_hook( parents, request, sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2], ) retry = True finally: # Note: 'abort's can fail. Nevertheless, we want end request handling try: try: notify(PubBeforeAbort(request, exc_info, retry)) finally: if transactions_manager: transactions_manager.abort() finally: endInteraction() notify(PubFailure(request, exc_info, retry)) # Only reachable if Retry is raised and request supports retry. newrequest = request.retry() request.close() # Free resources held by the request. # Set the default layer/skin on the newly generated request if ISkinnable.providedBy(newrequest): setDefaultSkin(newrequest) try: return publish(newrequest, module_name, after_list, debug) finally: newrequest.close() else: # Note: 'abort's can fail. Nevertheless, we want end request handling try: try: notify(PubBeforeAbort(request, exc_info, False)) finally: if transactions_manager: transactions_manager.abort() finally: endInteraction() notify(PubFailure(request, exc_info, False)) raise
def publish_module(module_name, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr, environ=os.environ, debug=0, request=None, response=None, extra={}): """ Adapted from from ZPublisher.Test.publish_module: but we handle the response status like given from response.getStatus(), otherwise plone internal links will return status=200 for status=404 links, which will not throw an error. """ must_die = 0 status = 200 after_list = [None] from ZPublisher.Response import Response from ZPublisher.Request import Request from ZPublisher.Publish import publish from zope.publisher.interfaces import ISkinnable from zope.publisher.skinnable import setDefaultSkin try: try: if response is None: response = Response(stdout=stdout, stderr=stderr) else: stdout = response.stdout # debug is just used by tests (has nothing to do with debug_mode!) response.handle_errors = not debug if request is None: request = Request(stdin, environ, response) # make sure that the request we hand over has the # default layer/skin set on it; subsequent code that # wants to look up views will likely depend on it if ISkinnable.providedBy(request): setDefaultSkin(request) for k, v in extra.items(): request[k] = v response = publish(request, module_name, after_list, debug=debug) except (SystemExit, ImportError): # XXX: Rendered ImportErrors were never caught here because they # were re-raised as string exceptions. Maybe we should handle # ImportErrors like all other exceptions. Currently they are not # re-raised at all, so they don't show up here. must_die = sys.exc_info() request.response.exception(1) except Unauthorized: # Handle Unauthorized separately, otherwise it will be displayed as # a redirect to the login form status = 200 response = None except: # debug is just used by tests (has nothing to do with debug_mode!) if debug: raise request.response.exception() status = response.getStatus() if response: # this is our change: otherwise 404 will return 200 # but we only want "real" 404 - otherwise the list will get full # of internal links with edit-links stuff that will return 5xx # codes. if response.getStatus() in (301, 302, 404): status = response.getStatus() outputBody = getattr(response, 'outputBody', None) if outputBody is not None: outputBody() else: response = str(response) if response: stdout.write(response) # The module defined a post-access function, call it if after_list[0] is not None: after_list[0]() finally: if request is not None: request.close() if must_die: # Try to turn exception value into an exit code. try: if hasattr(must_die[1], 'code'): code = must_die[1].code else: code = int(must_die[1]) except: code = must_die[1] and 1 or 0 if hasattr(request.response, '_requestShutdown'): request.response._requestShutdown(code) try: raise must_die[0], must_die[1], must_die[2] finally: must_die = None return status, response
def process_wrapper(pid, request_body, request_environ): # Sets up everything we need to run a view method in a new Zope-ish # context, then runs it and stores the result for later retrieval. _process = None def my_mapply(object, positional=(), keyword={}, debug=None, maybe=None, missing_name=None, handle_class=None, context=None, bind=0): if not isinstance(keyword, Mapping): keyword = {} keyword['process_id'] = pid args = (getattr(object, '__run__', object),) kwargs = dict(positional=positional, keyword=keyword, debug=debug, maybe=maybe, context=context, bind=bind ) if missing_name is not None: kwargs['missing_name'] = missing_name if handle_class is not None: kwargs['handle_class'] = handle_class return mapply(*args, **kwargs) response = HTTPResponse(stdout=StringIO(), stderr=StringIO()) request = HTTPRequest(StringIO(request_body), request_environ, response) request.set('process_id', pid) import Zope2 app = Zope2.bobo_application.__bobo_traverse__(request) reg = getProcessRegistry(app) _process = reg.get(pid) # Run try: try: response = publish(request, 'Zope2', [None], mapply=my_mapply) # We can't just pass the response back, as the data streams will not # be set up right. attr = (hasattr(response, 'cookies') and 'cookies') or \ (hasattr(response, '_cookies') and '_cookies') cookies = deepcopy(getattr(response, attr)) if IHTTPResponse.providedBy(response): _process['result'] = (response.getStatus(), dict(response.getHeaders()), cookies, response.consumeBody()) else: # Currently, ZPublisher.HTTPResponse doesn't implement # IHTTPResponse, even though HTTPRequest implements # IHTTPRequest. _process['result'] = (response.getStatus(), dict(response.headers), cookies, response.body) except Exception, e: # Set result to the exception raised _process['result'] = e raise else:
def process_wrapper(pid, request_body, request_environ): # Sets up everything we need to run a view method in a new Zope-ish # context, then runs it and stores the result for later retrieval. _process = None def my_mapply(object, positional=(), keyword={}, debug=None, maybe=None, missing_name=None, handle_class=None, context=None, bind=0): if not isinstance(keyword, Mapping): keyword = {} keyword['process_id'] = pid args = (getattr(object, '__run__', object), ) kwargs = dict(positional=positional, keyword=keyword, debug=debug, maybe=maybe, context=context, bind=bind) if missing_name is not None: kwargs['missing_name'] = missing_name if handle_class is not None: kwargs['handle_class'] = handle_class return mapply(*args, **kwargs) response = HTTPResponse(stdout=StringIO(), stderr=StringIO()) request = HTTPRequest(StringIO(request_body), request_environ, response) request.set('process_id', pid) import Zope2 app = Zope2.bobo_application.__bobo_traverse__(request) reg = getProcessRegistry(app) _process = reg.get(pid) # Run try: try: response = publish(request, 'Zope2', [None], mapply=my_mapply) # We can't just pass the response back, as the data streams will not # be set up right. attr = (hasattr(response, 'cookies') and 'cookies') or \ (hasattr(response, '_cookies') and '_cookies') cookies = deepcopy(getattr(response, attr)) if IHTTPResponse.providedBy(response): _process['result'] = (response.getStatus(), dict(response.getHeaders()), cookies, response.consumeBody()) else: # Currently, ZPublisher.HTTPResponse doesn't implement # IHTTPResponse, even though HTTPRequest implements # IHTTPRequest. _process['result'] = (response.getStatus(), dict(response.headers), cookies, response.body) except Exception, e: # Set result to the exception raised _process['result'] = e raise else: