diff --git a/letsencrypt/client/plugins/nginx/configurator.py b/letsencrypt/client/plugins/nginx/configurator.py index a15d42eb2..4b3239538 100644 --- a/letsencrypt/client/plugins/nginx/configurator.py +++ b/letsencrypt/client/plugins/nginx/configurator.py @@ -109,8 +109,7 @@ class NginxConfigurator(object): the VHost associated with the given domain. If it can't find the directives, it searches the "included" confs. The function verifies that it has located the three directives and finally modifies them to point - to the correct destination. After the certificate is installed, the - VirtualHost is enabled if it isn't already. + to the correct destination. .. todo:: Make sure last directive is changed diff --git a/letsencrypt/client/plugins/nginx/obj.py b/letsencrypt/client/plugins/nginx/obj.py index 85a7fa003..6e20a78b5 100644 --- a/letsencrypt/client/plugins/nginx/obj.py +++ b/letsencrypt/client/plugins/nginx/obj.py @@ -1,21 +1,65 @@ """Module contains classes used by the Nginx Configurator.""" +import re class Addr(object): - r"""Represents an Nginx VirtualHost address. + """Represents an Nginx address, i.e. what comes after the 'listen' + directive. - :param str addr: addr part of vhost address - :param str port: port number or \*, or "" + According to http://nginx.org/en/docs/http/ngx_http_core_module.html#listen, + this may be address[:port], port, or unix:path. The latter is ignored here. + + The default value if no directive is specified is *:80 (superuser) or + *:8000 (otherwise). If no port is specified, the default is 80. If no + address is specified, listen on all addresses. + + :param str addr: addr part of vhost address, may be hostname, IPv4, IPv6, + "", or "*" + :param str port: port number or "*" or "" + :param bool ssl: Whether the directive includes 'ssl' + :param bool default: Whether the directive includes 'default_server' """ - def __init__(self, tup): - self.tup = tup + def __init__(self, host, port, ssl, default): + self.tup = (host, port) + self.ssl = ssl + self.default = default @classmethod def fromstring(cls, str_addr): """Initialize Addr from string.""" - tup = str_addr.partition(':') - return cls((tup[0], tup[2])) + parts = str_addr.split(' ') + ssl = False + default = False + host = '' + port = '' + + # The first part must be the address + addr = parts.pop(0) + + # Ignore UNIX-domain sockets + if addr.startswith('unix:'): + return None + + tup = addr.partition(':') + if re.match('^\d+$', tup[0]): + # This is a bare port, not a hostname. E.g. listen 80 + host = '' + port = tup[0] + else: + # This is a host-port tuple. E.g. listen 127.0.0.1:* + host = tup[0] + port = tup[2] + + # The rest of the parts are options; we only care about ssl and default + while len(parts) > 0: + nextpart = parts.pop() + if nextpart == 'ssl': + ssl = True + elif nextpart == 'default_server': + default = True + + return cls(host, port, ssl, default) def __str__(self): if self.tup[1]: diff --git a/letsencrypt/client/plugins/nginx/parser.py b/letsencrypt/client/plugins/nginx/parser.py index ad59911ec..acc1a9f36 100644 --- a/letsencrypt/client/plugins/nginx/parser.py +++ b/letsencrypt/client/plugins/nginx/parser.py @@ -113,7 +113,7 @@ class NginxParser(object): :rtype: bool """ - # Look for a server block that contains 'listen [port] ssl' + # Look for a server block that contains 'listen [...] ssl' return False def get_vhosts(self):