diff --git a/pywebfinger.py b/pywebfinger.py index d960652..3340921 100644 --- a/pywebfinger.py +++ b/pywebfinger.py @@ -17,69 +17,80 @@ WEBFINGER_TYPES = ( 'http://webfinger.info/rel/service', # deprecated on 09/17/2009 ) -class WebFingerExpection(Exception): +class WebFingerException(Exception): pass class WebFingerResponse(object): - - def __init__(self, xrd): + + def __init__(self, xrd, insecure): + self.insecure = insecure self._xrd = xrd - + def __getattr__(self, name): if name in RELS: return self._xrd.find_link(RELS[name], attr='href') return getattr(self._xrd, name) class WebFingerClient(object): - - def __init__(self, host, secure=False): + + def __init__(self, host, timeout=None): self._host = host - self._secure = secure self._opener = urllib2.build_opener(urllib2.HTTPRedirectHandler()) self._opener.addheaders = [('User-agent', 'python-webfinger')] - + + self._timeout = timeout + def _hm_hosts(self, xrd): return [e.value for e in xrd.elements if e.name == 'hm:Host'] - + def xrd(self, url, raw=False): - conn = self._opener.open(url) + conn = self._opener.open(url, timeout=self._timeout) response = conn.read() conn.close() return response if raw else XRD.parse(response) - - def hostmeta(self): - protocol = "https" if self._secure else "http" + + def hostmeta(self, protocol): hostmeta_url = "%s://%s/.well-known/host-meta" % (protocol, self._host) return self.xrd(hostmeta_url) - + def finger(self, username): - - hm = self.hostmeta() + try: + hm = self.hostmeta('https') + insecure = False + except (urllib2.URLError, urllib2.HTTPError): + hm = self.hostmeta('http') + insecure = True + hm_hosts = self._hm_hosts(hm) - + if self._host not in hm_hosts: - raise WebFingerExpection("hostmeta host did not match account host") - + raise WebFingerException("hostmeta host did not match account host") + template = hm.find_link(WEBFINGER_TYPES, attr='template') + if not template.startswith('https://'): + insecure = True xrd_url = template.replace('{uri}', urllib.quote_plus('acct:%s@%s' % (username, self._host))) - - return WebFingerResponse(self.xrd(xrd_url)) -def finger(identifier, secure=False): + data = self.xrd(xrd_url) + return WebFingerResponse(data, insecure) + +def finger(identifier, timeout=None): if identifier.startswith('acct:'): (acct, identifier) = identifier.split(':', 1) (username, host) = identifier.split('@') - client = WebFingerClient(host, secure) + client = WebFingerClient(host, timeout=timeout) return client.finger(username) # example main method if __name__ == '__main__': import sys - wf = finger(sys.argv[1], True) + wf = finger(sys.argv[1]) print "Avatar: ", wf.avatar print "HCard: ", wf.hcard print "OpenID: ", wf.open_id print "Profile:", wf.profile print "XFN: ", wf.find_link('http://gmpg.org/xfn/11', attr='href') + if wf.insecure: + print "Warning: Data was retrieved over an insecure connection"