om@3
|
1 |
"""
|
om@3
|
2 |
Network Utilities
|
om@3
|
3 |
(from web.py)
|
om@3
|
4 |
"""
|
om@3
|
5 |
|
om@3
|
6 |
__all__ = [
|
om@3
|
7 |
"validipaddr", "validipport", "validip", "validaddr",
|
om@3
|
8 |
"urlquote",
|
om@3
|
9 |
"httpdate", "parsehttpdate",
|
om@3
|
10 |
"htmlquote", "htmlunquote", "websafe",
|
om@3
|
11 |
]
|
om@3
|
12 |
|
om@3
|
13 |
import urllib, time
|
om@3
|
14 |
try: import datetime
|
om@3
|
15 |
except ImportError: pass
|
om@3
|
16 |
|
om@3
|
17 |
def validipaddr(address):
|
om@3
|
18 |
"""
|
om@3
|
19 |
Returns True if `address` is a valid IPv4 address.
|
om@3
|
20 |
|
om@3
|
21 |
>>> validipaddr('192.168.1.1')
|
om@3
|
22 |
True
|
om@3
|
23 |
>>> validipaddr('192.168.1.800')
|
om@3
|
24 |
False
|
om@3
|
25 |
>>> validipaddr('192.168.1')
|
om@3
|
26 |
False
|
om@3
|
27 |
"""
|
om@3
|
28 |
try:
|
om@3
|
29 |
octets = address.split('.')
|
om@3
|
30 |
if len(octets) != 4:
|
om@3
|
31 |
return False
|
om@3
|
32 |
for x in octets:
|
om@3
|
33 |
if not (0 <= int(x) <= 255):
|
om@3
|
34 |
return False
|
om@3
|
35 |
except ValueError:
|
om@3
|
36 |
return False
|
om@3
|
37 |
return True
|
om@3
|
38 |
|
om@3
|
39 |
def validipport(port):
|
om@3
|
40 |
"""
|
om@3
|
41 |
Returns True if `port` is a valid IPv4 port.
|
om@3
|
42 |
|
om@3
|
43 |
>>> validipport('9000')
|
om@3
|
44 |
True
|
om@3
|
45 |
>>> validipport('foo')
|
om@3
|
46 |
False
|
om@3
|
47 |
>>> validipport('1000000')
|
om@3
|
48 |
False
|
om@3
|
49 |
"""
|
om@3
|
50 |
try:
|
om@3
|
51 |
if not (0 <= int(port) <= 65535):
|
om@3
|
52 |
return False
|
om@3
|
53 |
except ValueError:
|
om@3
|
54 |
return False
|
om@3
|
55 |
return True
|
om@3
|
56 |
|
om@3
|
57 |
def validip(ip, defaultaddr="0.0.0.0", defaultport=8080):
|
om@3
|
58 |
"""Returns `(ip_address, port)` from string `ip_addr_port`"""
|
om@3
|
59 |
addr = defaultaddr
|
om@3
|
60 |
port = defaultport
|
om@3
|
61 |
|
om@3
|
62 |
ip = ip.split(":", 1)
|
om@3
|
63 |
if len(ip) == 1:
|
om@3
|
64 |
if not ip[0]:
|
om@3
|
65 |
pass
|
om@3
|
66 |
elif validipaddr(ip[0]):
|
om@3
|
67 |
addr = ip[0]
|
om@3
|
68 |
elif validipport(ip[0]):
|
om@3
|
69 |
port = int(ip[0])
|
om@3
|
70 |
else:
|
om@3
|
71 |
raise ValueError, ':'.join(ip) + ' is not a valid IP address/port'
|
om@3
|
72 |
elif len(ip) == 2:
|
om@3
|
73 |
addr, port = ip
|
om@3
|
74 |
if not validipaddr(addr) and validipport(port):
|
om@3
|
75 |
raise ValueError, ':'.join(ip) + ' is not a valid IP address/port'
|
om@3
|
76 |
port = int(port)
|
om@3
|
77 |
else:
|
om@3
|
78 |
raise ValueError, ':'.join(ip) + ' is not a valid IP address/port'
|
om@3
|
79 |
return (addr, port)
|
om@3
|
80 |
|
om@3
|
81 |
def validaddr(string_):
|
om@3
|
82 |
"""
|
om@3
|
83 |
Returns either (ip_address, port) or "/path/to/socket" from string_
|
om@3
|
84 |
|
om@3
|
85 |
>>> validaddr('/path/to/socket')
|
om@3
|
86 |
'/path/to/socket'
|
om@3
|
87 |
>>> validaddr('8000')
|
om@3
|
88 |
('0.0.0.0', 8000)
|
om@3
|
89 |
>>> validaddr('127.0.0.1')
|
om@3
|
90 |
('127.0.0.1', 8080)
|
om@3
|
91 |
>>> validaddr('127.0.0.1:8000')
|
om@3
|
92 |
('127.0.0.1', 8000)
|
om@3
|
93 |
>>> validaddr('fff')
|
om@3
|
94 |
Traceback (most recent call last):
|
om@3
|
95 |
...
|
om@3
|
96 |
ValueError: fff is not a valid IP address/port
|
om@3
|
97 |
"""
|
om@3
|
98 |
if '/' in string_:
|
om@3
|
99 |
return string_
|
om@3
|
100 |
else:
|
om@3
|
101 |
return validip(string_)
|
om@3
|
102 |
|
om@3
|
103 |
def urlquote(val):
|
om@3
|
104 |
"""
|
om@3
|
105 |
Quotes a string for use in a URL.
|
om@3
|
106 |
|
om@3
|
107 |
>>> urlquote('://?f=1&j=1')
|
om@3
|
108 |
'%3A//%3Ff%3D1%26j%3D1'
|
om@3
|
109 |
>>> urlquote(None)
|
om@3
|
110 |
''
|
om@3
|
111 |
>>> urlquote(u'\u203d')
|
om@3
|
112 |
'%E2%80%BD'
|
om@3
|
113 |
"""
|
om@3
|
114 |
if val is None: return ''
|
om@3
|
115 |
if not isinstance(val, unicode): val = str(val)
|
om@3
|
116 |
else: val = val.encode('utf-8')
|
om@3
|
117 |
return urllib.quote(val)
|
om@3
|
118 |
|
om@3
|
119 |
def httpdate(date_obj):
|
om@3
|
120 |
"""
|
om@3
|
121 |
Formats a datetime object for use in HTTP headers.
|
om@3
|
122 |
|
om@3
|
123 |
>>> import datetime
|
om@3
|
124 |
>>> httpdate(datetime.datetime(1970, 1, 1, 1, 1, 1))
|
om@3
|
125 |
'Thu, 01 Jan 1970 01:01:01 GMT'
|
om@3
|
126 |
"""
|
om@3
|
127 |
return date_obj.strftime("%a, %d %b %Y %H:%M:%S GMT")
|
om@3
|
128 |
|
om@3
|
129 |
def parsehttpdate(string_):
|
om@3
|
130 |
"""
|
om@3
|
131 |
Parses an HTTP date into a datetime object.
|
om@3
|
132 |
|
om@3
|
133 |
>>> parsehttpdate('Thu, 01 Jan 1970 01:01:01 GMT')
|
om@3
|
134 |
datetime.datetime(1970, 1, 1, 1, 1, 1)
|
om@3
|
135 |
"""
|
om@3
|
136 |
try:
|
om@3
|
137 |
t = time.strptime(string_, "%a, %d %b %Y %H:%M:%S %Z")
|
om@3
|
138 |
except ValueError:
|
om@3
|
139 |
return None
|
om@3
|
140 |
return datetime.datetime(*t[:6])
|
om@3
|
141 |
|
om@3
|
142 |
def htmlquote(text):
|
om@3
|
143 |
r"""
|
om@3
|
144 |
Encodes `text` for raw use in HTML.
|
om@3
|
145 |
|
om@3
|
146 |
>>> htmlquote(u"<'&\">")
|
om@3
|
147 |
u'<'&">'
|
om@3
|
148 |
"""
|
om@3
|
149 |
text = text.replace(u"&", u"&") # Must be done first!
|
om@3
|
150 |
text = text.replace(u"<", u"<")
|
om@3
|
151 |
text = text.replace(u">", u">")
|
om@3
|
152 |
text = text.replace(u"'", u"'")
|
om@3
|
153 |
text = text.replace(u'"', u""")
|
om@3
|
154 |
return text
|
om@3
|
155 |
|
om@3
|
156 |
def htmlunquote(text):
|
om@3
|
157 |
r"""
|
om@3
|
158 |
Decodes `text` that's HTML quoted.
|
om@3
|
159 |
|
om@3
|
160 |
>>> htmlunquote(u'<'&">')
|
om@3
|
161 |
u'<\'&">'
|
om@3
|
162 |
"""
|
om@3
|
163 |
text = text.replace(u""", u'"')
|
om@3
|
164 |
text = text.replace(u"'", u"'")
|
om@3
|
165 |
text = text.replace(u">", u">")
|
om@3
|
166 |
text = text.replace(u"<", u"<")
|
om@3
|
167 |
text = text.replace(u"&", u"&") # Must be done last!
|
om@3
|
168 |
return text
|
om@3
|
169 |
|
om@3
|
170 |
def websafe(val):
|
om@3
|
171 |
r"""Converts `val` so that it is safe for use in Unicode HTML.
|
om@3
|
172 |
|
om@3
|
173 |
>>> websafe("<'&\">")
|
om@3
|
174 |
u'<'&">'
|
om@3
|
175 |
>>> websafe(None)
|
om@3
|
176 |
u''
|
om@3
|
177 |
>>> websafe(u'\u203d')
|
om@3
|
178 |
u'\u203d'
|
om@3
|
179 |
>>> websafe('\xe2\x80\xbd')
|
om@3
|
180 |
u'\u203d'
|
om@3
|
181 |
"""
|
om@3
|
182 |
if val is None:
|
om@3
|
183 |
return u''
|
om@3
|
184 |
elif isinstance(val, str):
|
om@3
|
185 |
val = val.decode('utf-8')
|
om@3
|
186 |
elif not isinstance(val, unicode):
|
om@3
|
187 |
val = unicode(val)
|
om@3
|
188 |
|
om@3
|
189 |
return htmlquote(val)
|
om@3
|
190 |
|
om@3
|
191 |
if __name__ == "__main__":
|
om@3
|
192 |
import doctest
|
om@3
|
193 |
doctest.testmod()
|