80 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			80 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
# -*- coding: utf-8 -*-
 | 
						|
# Copyright 2014-2016 OpenMarket Ltd
 | 
						|
#
 | 
						|
# Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
# you may not use this file except in compliance with the License.
 | 
						|
# You may obtain a copy of the License at
 | 
						|
#
 | 
						|
#     http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
#
 | 
						|
# Unless required by applicable law or agreed to in writing, software
 | 
						|
# distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
# See the License for the specific language governing permissions and
 | 
						|
# limitations under the License.
 | 
						|
import logging
 | 
						|
import re
 | 
						|
 | 
						|
logger = logging.getLogger(__name__)
 | 
						|
 | 
						|
 | 
						|
def parse_server_name(server_name):
 | 
						|
    """Split a server name into host/port parts.
 | 
						|
 | 
						|
    Args:
 | 
						|
        server_name (str): server name to parse
 | 
						|
 | 
						|
    Returns:
 | 
						|
        Tuple[str, int|None]: host/port parts.
 | 
						|
 | 
						|
    Raises:
 | 
						|
        ValueError if the server name could not be parsed.
 | 
						|
    """
 | 
						|
    try:
 | 
						|
        if server_name[-1] == "]":
 | 
						|
            # ipv6 literal, hopefully
 | 
						|
            return server_name, None
 | 
						|
 | 
						|
        domain_port = server_name.rsplit(":", 1)
 | 
						|
        domain = domain_port[0]
 | 
						|
        port = int(domain_port[1]) if domain_port[1:] else None
 | 
						|
        return domain, port
 | 
						|
    except Exception:
 | 
						|
        raise ValueError("Invalid server name '%s'" % server_name)
 | 
						|
 | 
						|
 | 
						|
VALID_HOST_REGEX = re.compile("\\A[0-9a-zA-Z.-]+\\Z")
 | 
						|
 | 
						|
 | 
						|
def parse_and_validate_server_name(server_name):
 | 
						|
    """Split a server name into host/port parts and do some basic validation.
 | 
						|
 | 
						|
    Args:
 | 
						|
        server_name (str): server name to parse
 | 
						|
 | 
						|
    Returns:
 | 
						|
        Tuple[str, int|None]: host/port parts.
 | 
						|
 | 
						|
    Raises:
 | 
						|
        ValueError if the server name could not be parsed.
 | 
						|
    """
 | 
						|
    host, port = parse_server_name(server_name)
 | 
						|
 | 
						|
    # these tests don't need to be bulletproof as we'll find out soon enough
 | 
						|
    # if somebody is giving us invalid data. What we *do* need is to be sure
 | 
						|
    # that nobody is sneaking IP literals in that look like hostnames, etc.
 | 
						|
 | 
						|
    # look for ipv6 literals
 | 
						|
    if host[0] == "[":
 | 
						|
        if host[-1] != "]":
 | 
						|
            raise ValueError("Mismatched [...] in server name '%s'" % (server_name,))
 | 
						|
        return host, port
 | 
						|
 | 
						|
    # otherwise it should only be alphanumerics.
 | 
						|
    if not VALID_HOST_REGEX.match(host):
 | 
						|
        raise ValueError(
 | 
						|
            "Server name '%s' contains invalid characters" % (server_name,)
 | 
						|
        )
 | 
						|
 | 
						|
    return host, port
 |