def __call__(self, req, form): """ Maybe resolve the final / of a directory """ # When this method is called, we either are a directory which # has an 'index' method, and we redirect to it, or we don't # have such a method, in which case it is a traversal error. if "" in self._exports: if not form: # Fix missing trailing slash as a convenience, unless # we are processing a form (in which case it is better # to fix the form posting). redirect_to_url( req, req.uri + "/", apache.HTTP_MOVED_PERMANENTLY) _debug(req, 'directory %r is not callable' % self) raise TraversalError()
def mp_legacy_publisher(req, possible_module, possible_handler): """ mod_python legacy publisher minimum implementation. """ from invenio.ext.legacy.handler import CFG_HAS_HTTPS_SUPPORT, CFG_FULL_HTTPS if possible_module.endswith('.pyc'): possible_module = possible_module[:-1] the_module = open(possible_module).read() module_globals = {} exec(the_module, module_globals) if possible_handler in module_globals and callable( module_globals[possible_handler]): from invenio.ext.legacy.handler import _check_result ## req is the required first parameter of any handler expected_args = list( inspect.getargspec(module_globals[possible_handler])[0]) if not expected_args or 'req' != expected_args[0]: ## req was not the first argument. Too bad! raise SERVER_RETURN, HTTP_NOT_FOUND ## the req.form must be casted to dict because of Python 2.4 and earlier ## otherwise any object exposing the mapping interface can be ## used with the magic ** form = dict() for key, value in req.form.items(): ## FIXME: this is a backward compatibility workaround ## because most of the old administration web handler ## expect parameters to be of type str. ## When legacy publisher will be removed all this ## pain will go away anyway :-) if isinstance(value, unicode): form[key] = value.encode('utf8') else: ## NOTE: this is a workaround for e.g. legacy webupload ## that is still using legacy publisher and expect to ## have a file (Field) instance instead of a string. form[key] = value if (CFG_FULL_HTTPS or CFG_HAS_HTTPS_SUPPORT and session.need_https) and not req.is_https(): from invenio_utils.url import redirect_to_url # We need to isolate the part of the URI that is after # CFG_SITE_URL, and append that to our CFG_SITE_SECURE_URL. original_parts = urlparse(req.unparsed_uri) plain_prefix_parts = urlparse(CFG_SITE_URL) secure_prefix_parts = urlparse(CFG_SITE_SECURE_URL) # Compute the new path plain_path = original_parts[2] plain_path = secure_prefix_parts[2] + \ plain_path[len(plain_prefix_parts[2]):] # ...and recompose the complete URL final_parts = list(secure_prefix_parts) final_parts[2] = plain_path final_parts[-3:] = original_parts[-3:] target = urlunparse(final_parts) redirect_to_url(req, target) try: return _check_result(req, module_globals[possible_handler](req, **form)) except TypeError as err: if ("%s() got an unexpected keyword argument" % possible_handler) in str(err) or ( '%s() takes at least' % possible_handler) in str(err): inspected_args = inspect.getargspec( module_globals[possible_handler]) expected_args = list(inspected_args[0]) expected_defaults = list(inspected_args[3]) expected_args.reverse() expected_defaults.reverse() register_exception( req=req, prefix= "Wrong GET parameter set in calling a legacy publisher handler for %s: expected_args=%s, found_args=%s" % (possible_handler, repr(expected_args), repr(req.form.keys())), alert_admin=CFG_DEVEL_SITE) cleaned_form = {} for index, arg in enumerate(expected_args): if arg == 'req': continue if index < len(expected_defaults): cleaned_form[arg] = form.get(arg, expected_defaults[index]) else: cleaned_form[arg] = form.get(arg, None) return _check_result( req, module_globals[possible_handler](req, **cleaned_form)) else: raise else: raise SERVER_RETURN, HTTP_NOT_FOUND
def mp_legacy_publisher(req, possible_module, possible_handler): """ mod_python legacy publisher minimum implementation. """ from invenio.ext.legacy.handler import CFG_HAS_HTTPS_SUPPORT, CFG_FULL_HTTPS if possible_module.endswith(".pyc"): possible_module = possible_module[:-1] the_module = open(possible_module).read() module_globals = {} exec(the_module, module_globals) if possible_handler in module_globals and callable(module_globals[possible_handler]): from invenio.ext.legacy.handler import _check_result ## req is the required first parameter of any handler expected_args = list(inspect.getargspec(module_globals[possible_handler])[0]) if not expected_args or "req" != expected_args[0]: ## req was not the first argument. Too bad! raise SERVER_RETURN, HTTP_NOT_FOUND ## the req.form must be casted to dict because of Python 2.4 and earlier ## otherwise any object exposing the mapping interface can be ## used with the magic ** form = dict() for key, value in req.form.items(): ## FIXME: this is a backward compatibility workaround ## because most of the old administration web handler ## expect parameters to be of type str. ## When legacy publisher will be removed all this ## pain will go away anyway :-) if isinstance(value, unicode): form[key] = value.encode("utf8") else: ## NOTE: this is a workaround for e.g. legacy webupload ## that is still using legacy publisher and expect to ## have a file (Field) instance instead of a string. form[key] = value if (CFG_FULL_HTTPS or CFG_HAS_HTTPS_SUPPORT and session.need_https) and not req.is_https(): from invenio_utils.url import redirect_to_url # We need to isolate the part of the URI that is after # CFG_SITE_URL, and append that to our CFG_SITE_SECURE_URL. original_parts = urlparse(req.unparsed_uri) plain_prefix_parts = urlparse(CFG_SITE_URL) secure_prefix_parts = urlparse(CFG_SITE_SECURE_URL) # Compute the new path plain_path = original_parts[2] plain_path = secure_prefix_parts[2] + plain_path[len(plain_prefix_parts[2]) :] # ...and recompose the complete URL final_parts = list(secure_prefix_parts) final_parts[2] = plain_path final_parts[-3:] = original_parts[-3:] target = urlunparse(final_parts) redirect_to_url(req, target) try: return _check_result(req, module_globals[possible_handler](req, **form)) except TypeError as err: if ("%s() got an unexpected keyword argument" % possible_handler) in str(err) or ( "%s() takes at least" % possible_handler ) in str(err): inspected_args = inspect.getargspec(module_globals[possible_handler]) expected_args = list(inspected_args[0]) expected_defaults = list(inspected_args[3]) expected_args.reverse() expected_defaults.reverse() register_exception( req=req, prefix="Wrong GET parameter set in calling a legacy publisher handler for %s: expected_args=%s, found_args=%s" % (possible_handler, repr(expected_args), repr(req.form.keys())), alert_admin=CFG_DEVEL_SITE, ) cleaned_form = {} for index, arg in enumerate(expected_args): if arg == "req": continue if index < len(expected_defaults): cleaned_form[arg] = form.get(arg, expected_defaults[index]) else: cleaned_form[arg] = form.get(arg, None) return _check_result(req, module_globals[possible_handler](req, **cleaned_form)) else: raise else: raise SERVER_RETURN, HTTP_NOT_FOUND
def _traverse(self, req, path, do_head=False, guest_p=True): """ Locate the handler of an URI by traversing the elements of the path.""" _debug(req, 'traversing %r' % path) component, path = path[0], path[1:] name = self._translate(component) if name is None: obj, path = self._lookup(component, path) else: obj = getattr(self, name) if obj is None: _debug(req, 'could not resolve %s' % repr((component, path))) raise TraversalError() # We have found the next segment. If we know that from this # point our subpages are over HTTPS, do the switch. if (CFG_FULL_HTTPS or CFG_HAS_HTTPS_SUPPORT and ( self._force_https or session.need_https() )) and not req.is_https(): # We need to isolate the part of the URI that is after # CFG_SITE_URL, and append that to our CFG_SITE_SECURE_URL. original_parts = urlparse.urlparse(req.unparsed_uri) plain_prefix_parts = urlparse.urlparse(CFG_SITE_URL) secure_prefix_parts = urlparse.urlparse(CFG_SITE_SECURE_URL) # Compute the new path plain_path = original_parts[2] plain_path = secure_prefix_parts[2] + \ plain_path[len(plain_prefix_parts[2]):] # ...and recompose the complete URL final_parts = list(secure_prefix_parts) final_parts[2] = plain_path final_parts[-3:] = original_parts[-3:] target = urlparse.urlunparse(final_parts) # The following condition used to allow certain URLs to # by-pass the forced SSL redirect. Since SSL certificates # are deployed on INSPIRE, this is no longer needed # Will be left here for reference. # from invenio.config import CFG_INSPIRE_SITE # if not CFG_INSPIRE_SITE or # plain_path.startswith('/youraccount/login'): redirect_to_url(req, target) # Continue the traversal. If there is a path, continue # resolving, otherwise call the method as it is our final # renderer. We even pass it the parsed form arguments. if path: if hasattr(obj, '_traverse'): return obj._traverse(req, path, do_head, guest_p) else: raise apache.SERVER_RETURN(apache.HTTP_NOT_FOUND) if do_head: req.content_type = "text/html; charset=UTF-8" raise apache.SERVER_RETURN(apache.DONE) warnings.warn("Accessed deprecated page {0.uri}".format(req), PendingDeprecationWarning, stacklevel=2) form = req.form result = _check_result(req, obj(req, form)) return result