def _should_use_fr_error_handler(self): """ Determine if error should be handled with FR or default Flask The goal is to return Flask error handlers for non-FR-related routes, and FR errors (with the correct media type) for FR endpoints. This method currently handles 404 and 405 errors. :return: bool """ adapter = current_app.create_url_adapter(request) try: adapter.match() except MethodNotAllowed as e: # Check if the other HTTP methods at this url would hit the Api valid_route_method = e.valid_methods[0] rule, _ = adapter.match(method=valid_route_method, return_rule=True) return self.owns_endpoint(rule.endpoint) except NotFound: return self.catch_all_404s except Exception: # Werkzeug throws other kinds of exceptions, such as Redirect pass
def _response_format_from_path(request): # This means: using <format> for anything but dot-notation is really # a bad idea here. adapter = current_app.create_url_adapter(request) try: return adapter.match()[1].get('format') except NotFound: return None
def __init__(self, *args, **kwargs): super(RedirectForm, self).__init__(*args, **kwargs) if not self.next.data: self.next.data = request.args.get("next") or request.referrer try: ref_url = urlparse(self.next.data) if ref_url.path == "/": self.next.data = "user/schemas" else: # Will raise an exception if no endpoint exists for the url current_app.create_url_adapter(request).match(ref_url.path) except NotFound: print("not found") self.next.data = "user/schemas" except HTTPException: # Any other exceptions pass
def endpoint_for(url, method=None, return_rule=False, follow_redirects=True): """ Given an absolute URL, retrieve the matching endpoint name (or rule) and view arguments. Requires a current request context to determine runtime environment. :param str method: HTTP method to use (defaults to GET) :param bool return_rule: Return the URL rule instead of the endpoint name :param bool follow_redirects: Follow redirects to final endpoint :return: Tuple of endpoint name or URL rule or `None`, view arguments """ parsed_url = urlsplit(url) if not parsed_url.netloc: # We require an absolute URL return None, {} # Take the current runtime environment... environ = dict(request.environ) # ...but replace the HTTP host with the URL's host... environ['HTTP_HOST'] = parsed_url.netloc # ...and the path with the URL's path (after discounting the app path, if not hosted at root). environ['PATH_INFO'] = parsed_url.path[len(environ.get('SCRIPT_NAME', '')):] # Create a new request with this environment... url_request = current_app.request_class(environ) # ...and a URL adapter with the new request. url_adapter = current_app.create_url_adapter(url_request) # Run three hostname tests, one of which must pass: # 1. Does the URL map have host matching enabled? If so, the URL adapter will validate the hostname. if current_app.url_map.host_matching: pass # 2. If not, does the domain match? url_adapter.server_name will prefer app.config['SERVER_NAME'], # but if that is not specified, it will take it from the environment. elif parsed_url.netloc == url_adapter.server_name: pass # 3. If subdomain matching is enabled, does the subdomain match? elif current_app.subdomain_matching and parsed_url.netloc.endswith('.' + url_adapter.server_name): pass # If no test passed, we don't have a matching endpoint. else: return None, {} # Now retrieve the endpoint or rule, watching for redirects or resolution failures try: return url_adapter.match(parsed_url.path, method, return_rule=return_rule) except RequestRedirect as r: # A redirect typically implies `/folder` -> `/folder/` # This will not be a redirect response from a view, since the view isn't being called if follow_redirects: return endpoint_for(r.new_url, method=method, return_rule=return_rule, follow_redirects=follow_redirects) except (NotFound, MethodNotAllowed): pass # If we got here, no endpoint was found. return None, {}
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if not self.next.data: # self.next.data = request.args.get("next") or request.referrer self.next.data = request.args.get("next") or "user/schemas" try: ref_url = urlparse(self.next.data) if ref_url.path == "/": self.next.data = "user/schemas" else: # Will raise an exception if no endpoint exists for the url adapter = current_app.create_url_adapter(request) adapter.match(ref_url.path) # type: ignore except NotFound: self.next.data = "user/schemas" except HTTPException: # Any other exceptions pass
def _should_use_fr_error_handler(self): """ Determine if error should be handled with FR or default Flask The goal is to return Flask error handlers for non-FR-related routes, and FR errors (with the correct media type) for FR endpoints. This method currently handles 404 and 405 errors. :return: bool """ adapter = current_app.create_url_adapter(request) try: adapter.match() except MethodNotAllowed as e: # Check if the other HTTP methods at this url would hit the Api valid_route_method = e.valid_methods[0] rule, _ = adapter.match(method=valid_route_method, return_rule=True) return self.owns_endpoint(rule.endpoint) except NotFound: return self.catch_all_404s except: # Werkzeug throws other kinds of exceptions, such as Redirect pass
def update_deposit(self, record: SWORDDeposit, replace: bool = True): """Update a deposit according to the request data :param replace: If ``True``, all previous data on the deposit is removed. If ``False``, the request augments data already provided. """ content_disposition, content_disposition_options = parse_options_header( request.headers.get("Content-Disposition", "")) metadata_deposit = content_disposition_options.get( "metadata") == "true" by_reference_deposit = content_disposition_options.get( "by-reference") == "true" if metadata_deposit: if by_reference_deposit: # pragma: nocover record.set_metadata( request.json["metadata"], self.metadata_class, replace=replace, ) else: record.set_metadata( request.stream, self.metadata_class, request.content_type, replace=replace, ) elif replace: record.set_metadata(None, self.metadata_class, replace=replace) if by_reference_deposit: by_reference_schema = ByReferenceSchema(context={ "url_adapter": current_app.create_url_adapter(request) }, ) if metadata_deposit: by_reference = by_reference_schema.load( request.json["by-reference"]) else: by_reference = by_reference_schema.load(request.json) record.set_by_reference_files( by_reference["files"], dereference_policy=self.endpoint_options["dereference_policy"], request_url=request.url, replace=replace, ) elif replace: record.set_by_reference_files( [], dereference_policy=self.endpoint_options["dereference_policy"], request_url=request.url, replace=replace, ) if not (metadata_deposit or by_reference_deposit) and ( request.content_type or request.content_length): self.ingest_file(record, request.stream, replace=replace) elif replace: self.ingest_file(record, None, replace=replace) self.update_deposit_status(record) record.commit() db.session.commit()
def endpoint_for(url, method=None, return_rule=False, follow_redirects=True): """ Given an absolute URL, retrieve the matching endpoint name (or rule) and view arguments. Requires a current request context to determine runtime environment. :param str method: HTTP method to use (defaults to GET) :param bool return_rule: Return the URL rule instead of the endpoint name :param bool follow_redirects: Follow redirects to final endpoint :return: Tuple of endpoint name or URL rule or `None`, view arguments """ parsed_url = urlsplit(url) if not parsed_url.netloc: # We require an absolute URL return None, {} # Take the current runtime environment... environ = dict(request.environ) # ...but replace the HTTP host with the URL's host... environ['HTTP_HOST'] = parsed_url.netloc # ...and the path with the URL's path (after discounting the app path, if not hosted at root). environ['PATH_INFO'] = parsed_url.path[len(environ.get('SCRIPT_NAME', '') ):] # Create a new request with this environment... url_request = current_app.request_class(environ) # ...and a URL adapter with the new request. url_adapter = current_app.create_url_adapter(url_request) # Run three hostname tests, one of which must pass: # 1. Does the URL map have host matching enabled? If so, the URL adapter will validate the hostname. if current_app.url_map.host_matching: pass # 2. If not, does the domain match? url_adapter.server_name will prefer app.config['SERVER_NAME'], # but if that is not specified, it will take it from the environment. elif parsed_url.netloc == url_adapter.server_name: pass # 3. If subdomain matching is enabled, does the subdomain match? elif current_app.subdomain_matching and parsed_url.netloc.endswith( '.' + url_adapter.server_name): pass # If no test passed, we don't have a matching endpoint. else: return None, {} # Now retrieve the endpoint or rule, watching for redirects or resolution failures try: return url_adapter.match(parsed_url.path, method, return_rule=return_rule) except RequestRedirect as r: # A redirect typically implies `/folder` -> `/folder/` # This will not be a redirect response from a view, since the view isn't being called if follow_redirects: return endpoint_for(r.new_url, method=method, return_rule=return_rule, follow_redirects=follow_redirects) except (NotFound, MethodNotAllowed): pass # If we got here, no endpoint was found. return None, {}