Repository: certbot/certbot

Issue:
timeout on certbot-auto update check if pypy.python.org is unreachable
similar to #4074, #3313, #3636
## My operating system is (include version):
`Linux Debian-85-jessie-64-minimal 4.9.0-2-amd64 #1 SMP Debian 4.9.13-1 (2017-02-27) x86_64 GNU/Linux`

## I installed Certbot with (certbot-auto, OS package manager, pip, etc):
git clone (certbot-auto)

## I ran this command and it produced this output:
When I try to run certbot-auto nothing happens until I press CTRL+C and get:
```
Traceback (most recent call last):
  File "/tmp/tmp.bPi8RZRS1H/fetch.py", line 126, in <module>
    exit(main())
  File "/tmp/tmp.bPi8RZRS1H/fetch.py", line 114, in main
    print latest_stable_version(get)
  File "/tmp/tmp.bPi8RZRS1H/fetch.py", line 71, in latest_stable_version
    'https://pypi.python.org/pypi/certbot/json')))
  File "/tmp/tmp.bPi8RZRS1H/fetch.py", line 56, in get
    return self._opener.open(url).read()
  File "/usr/lib/python2.7/urllib2.py", line 429, in open
    response = self._open(req, data)
  File "/usr/lib/python2.7/urllib2.py", line 447, in _open
    '_open', req)
  File "/usr/lib/python2.7/urllib2.py", line 407, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 1241, in https_open
    context=self._context)
  File "/usr/lib/python2.7/urllib2.py", line 1201, in do_open
    r = h.getresponse(buffering=True)
  File "/usr/lib/python2.7/httplib.py", line 1121, in getresponse
    response.begin()
  File "/usr/lib/python2.7/httplib.py", line 438, in begin
    version, status, reason = self._read_status()
  File "/usr/lib/python2.7/httplib.py", line 394, in _read_status
    line = self.fp.readline(_MAXLINE + 1)
  File "/usr/lib/python2.7/socket.py", line 480, in readline
    data = self._sock.recv(self._rbufsize)
  File "/usr/lib/python2.7/ssl.py", line 766, in recv
    return self.read(buflen)
  File "/usr/lib/python2.7/ssl.py", line 653, in read
    v = self._sslobj.read(len)
KeyboardInterrupt
```
`curl https://pypi.python.org/pypi/certbot/json` also just hangs on my server and on my local computer

The error seems to be at pypi.python.org:
![screenshot_20170406_143445](https://cloud.githubusercontent.com/assets/6266037/24754331/4ce0594a-1ad6-11e7-8c30-5089a363cfa3.png)


## Certbot's behavior differed from what I expected because:

It would be nice if certbot could skip the version check if pypi.python.org is not available.


Discussion:
> It would be nice if certbot could skip the version check if pypi.python.org is not available.

--no-self-upgrade?
> --no-self-upgrade?

That's nice, but it would be even better if it would skip it automatically if there is no response after X seconds.
@Findus23 we could do that, or we could do #4371, or we could do both in one PR?

Resolving patch:
diff --git a/letsencrypt-auto-source/pieces/fetch.py b/letsencrypt-auto-source/pieces/fetch.py
--- a/letsencrypt-auto-source/pieces/fetch.py
+++ b/letsencrypt-auto-source/pieces/fetch.py
@@ -20,7 +20,8 @@
 import re
 from subprocess import check_call, CalledProcessError
 from sys import argv, exit
-from urllib2 import build_opener, HTTPHandler, HTTPSHandler, HTTPError
+from urllib2 import build_opener, HTTPHandler, HTTPSHandler
+from urllib2 import HTTPError, URLError
 
 PUBLIC_KEY = environ.get('LE_AUTO_PUBLIC_KEY', """-----BEGIN PUBLIC KEY-----
 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6MR8W/galdxnpGqBsYbq
@@ -56,7 +57,9 @@ def get(self, url):
 
         """
         try:
-            return self._opener.open(url).read()
+            # socket module docs say default timeout is None: that is, no
+            # timeout
+            return self._opener.open(url, timeout=30).read()
         except (HTTPError, IOError) as exc:
             raise ExpectedError("Couldn't download %s." % url, exc)
 


Test patch: