def _create_forwarded_url(self, request_url): """Constructs a destination endpoint to request. Finds the matching URL pattern for the request_url. Anything trailing the pattern is appended to _forwarding_url to construct the final destination URL. Args: request_url: Incoming request URL from the client to be matched to a URL pattern and parsed to form the final destination URL. Returns: Final destination URL to which the incoming request should be forwarded. Raises: RequestError: The incoming request did not match any URL patterns for this route. """ url_pattern = self._find_pattern_for_request(request_url) if not url_pattern: raise RequestError('Requested URL "{0}" did not match the ' 'forwarding route "{1}"'.format( request_url, ', '.join(self._url_patterns))) url_pattern_escaped = re.escape(url_pattern) forwarded_url = re.subn(url_pattern_escaped, self._forwarding_url, request_url, 1, re.IGNORECASE) return forwarded_url[0]
def _create_forwarded_urls(self, request_url): """Constructs the destination endpoint(s) to request. Finds the matching URL pattern for the request_url. Once found, the final destination URLs are determined based on the endpoint IDs specified in the request in place of the wildcard section of the URL pattern. Finally, anything trailing the URL pattern is appended to each destination URL. Args: request_url: Incoming request URL from the client to be matched to a URL pattern and parsed to form the final destination URL(s). Returns: List of final destination URL(s) to which the incoming request should be forwarded. Raises: RequestError: The incoming request did not match any URL patterns for this route. """ # Extract endpoints from request url_pattern = self._find_pattern_for_request(request_url) url_pattern_parts = url_pattern.split(ENDPOINTS_WILDCARD) match_expression = re.escape(url_pattern_parts[0]) + \ "(?P<endpoint_ids>.*)" + \ re.escape(url_pattern_parts[1]) endpoint_ids_group = re.match(match_expression, request_url).group("endpoint_ids") endpoint_ids = endpoint_ids_group.split(',') endpoint_ids = [urllib.unquote(e_id) for e_id in endpoint_ids] endpoint_ids = [e_id.strip().lower() for e_id in endpoint_ids] # Extract trailing portion of request URL trailing_route = request_url[len(url_pattern_parts[0] + endpoint_ids_group + url_pattern_parts[1]):] # Create final URLs to be forwarded endpoint_urls = [] all_endpoints = False if '*' in endpoint_ids: all_endpoints = True for endpoint_id in self._endpoints: if all_endpoints or endpoint_id in endpoint_ids: url = self._endpoints[endpoint_id] + trailing_route endpoint_urls.append( self._resolve_query_string(url, endpoint_id) ) if len(endpoint_urls) == 0: raise RequestError('The incoming request did not specify a valid ' 'endpoint identifier for matched route: {0}' .format(url_pattern)) return endpoint_urls
def _match_route(self, request_url): """Matches an incoming request to a configured route. Args: request_url: URL of the incoming request. Returns: Route matching the incoming request. Raises: RequestError: A suitable route wasn't found to handle the incoming request. """ for route in self._routes: if route.match(request_url): return route raise RequestError('Unable to find a route to handle the request ' 'to {0}'.format(request_url))