1
2 __all__ = ['discover', 'DiscoveryResult', 'DiscoveryFailure']
3
4 from cStringIO import StringIO
5
6 from urljr import fetchers
7
8 from yadis.constants import \
9 YADIS_HEADER_NAME, YADIS_CONTENT_TYPE, YADIS_ACCEPT_HEADER
10 from yadis.parsehtml import MetaNotFound, findHTMLMeta
11
13 """Raised when a YADIS protocol error occurs in the discovery process"""
14 identity_url = None
15
16 - def __init__(self, message, http_response):
17 Exception.__init__(self, message)
18 self.http_response = http_response
19
54
56 """Discover services for a given URI.
57
58 @param uri: The identity URI as a well-formed http or https
59 URI. The well-formedness and the protocol are not checked, but
60 the results of this function are undefined if those properties
61 do not hold.
62
63 @return: DiscoveryResult object
64
65 @raises Exception: Any exception that can be raised by fetching a URL with
66 the given fetcher.
67 """
68 result = DiscoveryResult(uri)
69 resp = fetchers.fetch(uri, headers={'Accept': YADIS_ACCEPT_HEADER})
70 if resp.status != 200:
71 raise DiscoveryFailure(
72 'HTTP Response status from identity URL host is not 200. '
73 'Got status %r' % (resp.status,), resp)
74
75
76 result.normalized_uri = resp.final_url
77
78
79
80 result.content_type = resp.headers.get('content-type')
81
82
83
84 if (result.content_type and
85 result.content_type.split(';', 1)[0].lower() == YADIS_CONTENT_TYPE):
86 result.xrds_uri = result.normalized_uri
87 else:
88
89 yadis_loc = resp.headers.get(YADIS_HEADER_NAME.lower())
90
91 if not yadis_loc:
92
93
94
95
96
97 try:
98 yadis_loc = findHTMLMeta(StringIO(resp.body))
99 except MetaNotFound:
100 pass
101
102
103
104
105 if yadis_loc:
106 result.xrds_uri = yadis_loc
107 resp = fetchers.fetch(yadis_loc)
108 if resp.status != 200:
109 exc = DiscoveryFailure(
110 'HTTP Response status from Yadis host is not 200. '
111 'Got status %r' % (resp.status,), resp)
112 exc.identity_url = result.normalized_uri
113 raise exc
114 result.content_type = resp.headers.get('content-type')
115
116 result.response_text = resp.body
117 return result
118