usr
/
lib64
/
python2.7
/
Go to Home Directory
+
Upload
Create File
root@0UT1S:~$
Execute
By Order of Mr.0UT1S
[DIR] ..
N/A
[DIR] Demo
N/A
[DIR] Doc
N/A
[DIR] Tools
N/A
[DIR] bsddb
N/A
[DIR] compiler
N/A
[DIR] config
N/A
[DIR] ctypes
N/A
[DIR] curses
N/A
[DIR] distutils
N/A
[DIR] email
N/A
[DIR] encodings
N/A
[DIR] ensurepip
N/A
[DIR] hotshot
N/A
[DIR] idlelib
N/A
[DIR] importlib
N/A
[DIR] json
N/A
[DIR] lib-dynload
N/A
[DIR] lib-tk
N/A
[DIR] lib2to3
N/A
[DIR] logging
N/A
[DIR] multiprocessing
N/A
[DIR] plat-linux2
N/A
[DIR] pydoc_data
N/A
[DIR] site-packages
N/A
[DIR] sqlite3
N/A
[DIR] test
N/A
[DIR] unittest
N/A
[DIR] wsgiref
N/A
[DIR] xml
N/A
BaseHTTPServer.py
22.21 KB
Rename
Delete
BaseHTTPServer.pyc
21.21 KB
Rename
Delete
BaseHTTPServer.pyo
21.21 KB
Rename
Delete
Bastion.py
5.61 KB
Rename
Delete
Bastion.pyc
6.50 KB
Rename
Delete
Bastion.pyo
6.50 KB
Rename
Delete
CGIHTTPServer.py
12.78 KB
Rename
Delete
CGIHTTPServer.pyc
10.76 KB
Rename
Delete
CGIHTTPServer.pyo
10.76 KB
Rename
Delete
ConfigParser.py
27.10 KB
Rename
Delete
ConfigParser.pyc
24.62 KB
Rename
Delete
ConfigParser.pyo
24.62 KB
Rename
Delete
Cookie.py
25.92 KB
Rename
Delete
Cookie.pyc
22.13 KB
Rename
Delete
Cookie.pyo
22.13 KB
Rename
Delete
DocXMLRPCServer.py
10.52 KB
Rename
Delete
DocXMLRPCServer.pyc
9.96 KB
Rename
Delete
DocXMLRPCServer.pyo
9.85 KB
Rename
Delete
HTMLParser.py
16.77 KB
Rename
Delete
HTMLParser.pyc
13.41 KB
Rename
Delete
HTMLParser.pyo
13.11 KB
Rename
Delete
MimeWriter.py
6.33 KB
Rename
Delete
MimeWriter.pyc
7.19 KB
Rename
Delete
MimeWriter.pyo
7.19 KB
Rename
Delete
Queue.py
8.38 KB
Rename
Delete
Queue.pyc
9.20 KB
Rename
Delete
Queue.pyo
9.20 KB
Rename
Delete
SimpleHTTPServer.py
7.81 KB
Rename
Delete
SimpleHTTPServer.pyc
7.82 KB
Rename
Delete
SimpleHTTPServer.pyo
7.82 KB
Rename
Delete
SimpleXMLRPCServer.py
25.21 KB
Rename
Delete
SimpleXMLRPCServer.pyc
22.33 KB
Rename
Delete
SimpleXMLRPCServer.pyo
22.33 KB
Rename
Delete
SocketServer.py
23.39 KB
Rename
Delete
SocketServer.pyc
23.52 KB
Rename
Delete
SocketServer.pyo
23.52 KB
Rename
Delete
StringIO.py
10.41 KB
Rename
Delete
StringIO.pyc
11.21 KB
Rename
Delete
StringIO.pyo
11.21 KB
Rename
Delete
UserDict.py
6.89 KB
Rename
Delete
UserDict.pyc
9.48 KB
Rename
Delete
UserDict.pyo
9.48 KB
Rename
Delete
UserList.py
3.56 KB
Rename
Delete
UserList.pyc
6.42 KB
Rename
Delete
UserList.pyo
6.42 KB
Rename
Delete
UserString.py
9.46 KB
Rename
Delete
UserString.pyc
14.52 KB
Rename
Delete
UserString.pyo
14.52 KB
Rename
Delete
_LWPCookieJar.py
6.40 KB
Rename
Delete
_LWPCookieJar.pyc
5.31 KB
Rename
Delete
_LWPCookieJar.pyo
5.31 KB
Rename
Delete
_MozillaCookieJar.py
5.66 KB
Rename
Delete
_MozillaCookieJar.pyc
4.36 KB
Rename
Delete
_MozillaCookieJar.pyo
4.32 KB
Rename
Delete
__future__.py
4.28 KB
Rename
Delete
__future__.pyc
4.12 KB
Rename
Delete
__future__.pyo
4.12 KB
Rename
Delete
__phello__.foo.py
64 bytes
Rename
Delete
__phello__.foo.pyc
125 bytes
Rename
Delete
__phello__.foo.pyo
125 bytes
Rename
Delete
_abcoll.py
18.18 KB
Rename
Delete
_abcoll.pyc
25.08 KB
Rename
Delete
_abcoll.pyo
25.08 KB
Rename
Delete
_osx_support.py
18.65 KB
Rename
Delete
_osx_support.pyc
11.48 KB
Rename
Delete
_osx_support.pyo
11.48 KB
Rename
Delete
_pyio.py
68.00 KB
Rename
Delete
_pyio.pyc
63.18 KB
Rename
Delete
_pyio.pyo
63.18 KB
Rename
Delete
_strptime.py
20.24 KB
Rename
Delete
_strptime.pyc
14.82 KB
Rename
Delete
_strptime.pyo
14.82 KB
Rename
Delete
_sysconfigdata.py
19.27 KB
Rename
Delete
_sysconfigdata.pyc
22.43 KB
Rename
Delete
_sysconfigdata.pyo
22.43 KB
Rename
Delete
_threading_local.py
7.09 KB
Rename
Delete
_threading_local.pyc
6.22 KB
Rename
Delete
_threading_local.pyo
6.22 KB
Rename
Delete
_weakrefset.py
5.77 KB
Rename
Delete
_weakrefset.pyc
9.45 KB
Rename
Delete
_weakrefset.pyo
9.45 KB
Rename
Delete
abc.py
6.98 KB
Rename
Delete
abc.pyc
6.00 KB
Rename
Delete
abc.pyo
5.94 KB
Rename
Delete
aifc.py
33.77 KB
Rename
Delete
aifc.pyc
29.75 KB
Rename
Delete
aifc.pyo
29.75 KB
Rename
Delete
antigravity.py
60 bytes
Rename
Delete
antigravity.pyc
203 bytes
Rename
Delete
antigravity.pyo
203 bytes
Rename
Delete
anydbm.py
2.60 KB
Rename
Delete
anydbm.pyc
2.73 KB
Rename
Delete
anydbm.pyo
2.73 KB
Rename
Delete
argparse.py
87.14 KB
Rename
Delete
argparse.pyc
62.86 KB
Rename
Delete
argparse.pyo
62.70 KB
Rename
Delete
ast.py
11.53 KB
Rename
Delete
ast.pyc
12.63 KB
Rename
Delete
ast.pyo
12.63 KB
Rename
Delete
asynchat.py
11.31 KB
Rename
Delete
asynchat.pyc
8.60 KB
Rename
Delete
asynchat.pyo
8.60 KB
Rename
Delete
asyncore.py
20.45 KB
Rename
Delete
asyncore.pyc
18.45 KB
Rename
Delete
asyncore.pyo
18.45 KB
Rename
Delete
atexit.py
1.67 KB
Rename
Delete
atexit.pyc
2.15 KB
Rename
Delete
atexit.pyo
2.15 KB
Rename
Delete
audiodev.py
7.42 KB
Rename
Delete
audiodev.pyc
8.27 KB
Rename
Delete
audiodev.pyo
8.27 KB
Rename
Delete
base64.py
11.53 KB
Rename
Delete
base64.pyc
11.03 KB
Rename
Delete
base64.pyo
11.03 KB
Rename
Delete
bdb.py
21.21 KB
Rename
Delete
bdb.pyc
18.65 KB
Rename
Delete
bdb.pyo
18.65 KB
Rename
Delete
binhex.py
14.35 KB
Rename
Delete
binhex.pyc
15.10 KB
Rename
Delete
binhex.pyo
15.10 KB
Rename
Delete
bisect.py
2.53 KB
Rename
Delete
bisect.pyc
3.00 KB
Rename
Delete
bisect.pyo
3.00 KB
Rename
Delete
cProfile.py
6.42 KB
Rename
Delete
cProfile.pyc
6.25 KB
Rename
Delete
cProfile.pyo
6.25 KB
Rename
Delete
calendar.py
22.84 KB
Rename
Delete
calendar.pyc
27.26 KB
Rename
Delete
calendar.pyo
27.26 KB
Rename
Delete
cgi.py
35.46 KB
Rename
Delete
cgi.pyc
32.58 KB
Rename
Delete
cgi.pyo
32.58 KB
Rename
Delete
cgitb.py
11.89 KB
Rename
Delete
cgitb.pyc
11.85 KB
Rename
Delete
cgitb.pyo
11.85 KB
Rename
Delete
chunk.py
5.29 KB
Rename
Delete
chunk.pyc
5.47 KB
Rename
Delete
chunk.pyo
5.47 KB
Rename
Delete
cmd.py
14.67 KB
Rename
Delete
cmd.pyc
13.71 KB
Rename
Delete
cmd.pyo
13.71 KB
Rename
Delete
code.py
9.95 KB
Rename
Delete
code.pyc
10.09 KB
Rename
Delete
code.pyo
10.09 KB
Rename
Delete
codecs.py
35.30 KB
Rename
Delete
codecs.pyc
35.96 KB
Rename
Delete
codecs.pyo
35.96 KB
Rename
Delete
codeop.py
5.86 KB
Rename
Delete
codeop.pyc
6.44 KB
Rename
Delete
codeop.pyo
6.44 KB
Rename
Delete
collections.py
27.15 KB
Rename
Delete
collections.pyc
25.55 KB
Rename
Delete
collections.pyo
25.50 KB
Rename
Delete
colorsys.py
3.60 KB
Rename
Delete
colorsys.pyc
3.90 KB
Rename
Delete
colorsys.pyo
3.90 KB
Rename
Delete
commands.py
2.49 KB
Rename
Delete
commands.pyc
2.41 KB
Rename
Delete
commands.pyo
2.41 KB
Rename
Delete
compileall.py
7.58 KB
Rename
Delete
compileall.pyc
6.85 KB
Rename
Delete
compileall.pyo
6.85 KB
Rename
Delete
contextlib.py
4.32 KB
Rename
Delete
contextlib.pyc
4.35 KB
Rename
Delete
contextlib.pyo
4.35 KB
Rename
Delete
cookielib.py
63.95 KB
Rename
Delete
cookielib.pyc
53.44 KB
Rename
Delete
cookielib.pyo
53.26 KB
Rename
Delete
copy.py
11.26 KB
Rename
Delete
copy.pyc
11.88 KB
Rename
Delete
copy.pyo
11.79 KB
Rename
Delete
copy_reg.py
6.81 KB
Rename
Delete
copy_reg.pyc
5.05 KB
Rename
Delete
copy_reg.pyo
5.00 KB
Rename
Delete
crypt.py
2.24 KB
Rename
Delete
crypt.pyc
2.89 KB
Rename
Delete
crypt.pyo
2.89 KB
Rename
Delete
csv.py
16.32 KB
Rename
Delete
csv.pyc
13.19 KB
Rename
Delete
csv.pyo
13.19 KB
Rename
Delete
dbhash.py
498 bytes
Rename
Delete
dbhash.pyc
718 bytes
Rename
Delete
dbhash.pyo
718 bytes
Rename
Delete
decimal.py
216.73 KB
Rename
Delete
decimal.pyc
168.12 KB
Rename
Delete
decimal.pyo
168.12 KB
Rename
Delete
difflib.py
80.40 KB
Rename
Delete
difflib.pyc
60.45 KB
Rename
Delete
difflib.pyo
60.40 KB
Rename
Delete
dircache.py
1.10 KB
Rename
Delete
dircache.pyc
1.54 KB
Rename
Delete
dircache.pyo
1.54 KB
Rename
Delete
dis.py
6.35 KB
Rename
Delete
dis.pyc
6.08 KB
Rename
Delete
dis.pyo
6.08 KB
Rename
Delete
doctest.py
102.63 KB
Rename
Delete
doctest.pyc
81.68 KB
Rename
Delete
doctest.pyo
81.40 KB
Rename
Delete
dumbdbm.py
8.93 KB
Rename
Delete
dumbdbm.pyc
6.59 KB
Rename
Delete
dumbdbm.pyo
6.59 KB
Rename
Delete
dummy_thread.py
4.31 KB
Rename
Delete
dummy_thread.pyc
5.27 KB
Rename
Delete
dummy_thread.pyo
5.27 KB
Rename
Delete
dummy_threading.py
2.74 KB
Rename
Delete
dummy_threading.pyc
1.25 KB
Rename
Delete
dummy_threading.pyo
1.25 KB
Rename
Delete
filecmp.py
9.36 KB
Rename
Delete
filecmp.pyc
9.40 KB
Rename
Delete
filecmp.pyo
9.40 KB
Rename
Delete
fileinput.py
13.42 KB
Rename
Delete
fileinput.pyc
14.16 KB
Rename
Delete
fileinput.pyo
14.16 KB
Rename
Delete
fnmatch.py
3.24 KB
Rename
Delete
fnmatch.pyc
3.53 KB
Rename
Delete
fnmatch.pyo
3.53 KB
Rename
Delete
formatter.py
14.56 KB
Rename
Delete
formatter.pyc
18.73 KB
Rename
Delete
formatter.pyo
18.73 KB
Rename
Delete
fpformat.py
4.62 KB
Rename
Delete
fpformat.pyc
4.59 KB
Rename
Delete
fpformat.pyo
4.59 KB
Rename
Delete
fractions.py
21.87 KB
Rename
Delete
fractions.pyc
19.25 KB
Rename
Delete
fractions.pyo
19.25 KB
Rename
Delete
ftplib.py
37.65 KB
Rename
Delete
ftplib.pyc
34.12 KB
Rename
Delete
ftplib.pyo
34.12 KB
Rename
Delete
functools.py
4.69 KB
Rename
Delete
functools.pyc
6.47 KB
Rename
Delete
functools.pyo
6.47 KB
Rename
Delete
genericpath.py
3.13 KB
Rename
Delete
genericpath.pyc
3.43 KB
Rename
Delete
genericpath.pyo
3.43 KB
Rename
Delete
getopt.py
7.15 KB
Rename
Delete
getopt.pyc
6.50 KB
Rename
Delete
getopt.pyo
6.45 KB
Rename
Delete
getpass.py
5.43 KB
Rename
Delete
getpass.pyc
4.63 KB
Rename
Delete
getpass.pyo
4.63 KB
Rename
Delete
gettext.py
22.13 KB
Rename
Delete
gettext.pyc
17.58 KB
Rename
Delete
gettext.pyo
17.58 KB
Rename
Delete
glob.py
3.04 KB
Rename
Delete
glob.pyc
2.87 KB
Rename
Delete
glob.pyo
2.87 KB
Rename
Delete
gzip.py
18.58 KB
Rename
Delete
gzip.pyc
14.88 KB
Rename
Delete
gzip.pyo
14.88 KB
Rename
Delete
hashlib.py
7.66 KB
Rename
Delete
hashlib.pyc
6.76 KB
Rename
Delete
hashlib.pyo
6.76 KB
Rename
Delete
heapq.py
17.87 KB
Rename
Delete
heapq.pyc
14.22 KB
Rename
Delete
heapq.pyo
14.22 KB
Rename
Delete
hmac.py
4.48 KB
Rename
Delete
hmac.pyc
4.44 KB
Rename
Delete
hmac.pyo
4.44 KB
Rename
Delete
htmlentitydefs.py
17.63 KB
Rename
Delete
htmlentitydefs.pyc
6.22 KB
Rename
Delete
htmlentitydefs.pyo
6.22 KB
Rename
Delete
htmllib.py
12.57 KB
Rename
Delete
htmllib.pyc
19.83 KB
Rename
Delete
htmllib.pyo
19.83 KB
Rename
Delete
httplib.py
52.06 KB
Rename
Delete
httplib.pyc
37.82 KB
Rename
Delete
httplib.pyo
37.64 KB
Rename
Delete
ihooks.py
18.54 KB
Rename
Delete
ihooks.pyc
20.87 KB
Rename
Delete
ihooks.pyo
20.87 KB
Rename
Delete
imaplib.py
47.23 KB
Rename
Delete
imaplib.pyc
43.96 KB
Rename
Delete
imaplib.pyo
41.32 KB
Rename
Delete
imghdr.py
3.46 KB
Rename
Delete
imghdr.pyc
4.72 KB
Rename
Delete
imghdr.pyo
4.72 KB
Rename
Delete
imputil.py
25.16 KB
Rename
Delete
imputil.pyc
15.26 KB
Rename
Delete
imputil.pyo
15.08 KB
Rename
Delete
inspect.py
42.00 KB
Rename
Delete
inspect.pyc
39.29 KB
Rename
Delete
inspect.pyo
39.29 KB
Rename
Delete
io.py
3.24 KB
Rename
Delete
io.pyc
3.50 KB
Rename
Delete
io.pyo
3.50 KB
Rename
Delete
keyword.py
1.95 KB
Rename
Delete
keyword.pyc
2.06 KB
Rename
Delete
keyword.pyo
2.06 KB
Rename
Delete
linecache.py
3.93 KB
Rename
Delete
linecache.pyc
3.20 KB
Rename
Delete
linecache.pyo
3.20 KB
Rename
Delete
locale.py
100.42 KB
Rename
Delete
locale.pyc
55.28 KB
Rename
Delete
locale.pyo
55.28 KB
Rename
Delete
macpath.py
6.14 KB
Rename
Delete
macpath.pyc
7.50 KB
Rename
Delete
macpath.pyo
7.50 KB
Rename
Delete
macurl2path.py
2.67 KB
Rename
Delete
macurl2path.pyc
2.19 KB
Rename
Delete
macurl2path.pyo
2.19 KB
Rename
Delete
mailbox.py
79.34 KB
Rename
Delete
mailbox.pyc
74.92 KB
Rename
Delete
mailbox.pyo
74.87 KB
Rename
Delete
mailcap.py
8.21 KB
Rename
Delete
mailcap.pyc
7.77 KB
Rename
Delete
mailcap.pyo
7.77 KB
Rename
Delete
markupbase.py
14.30 KB
Rename
Delete
markupbase.pyc
9.05 KB
Rename
Delete
markupbase.pyo
8.86 KB
Rename
Delete
md5.py
358 bytes
Rename
Delete
md5.pyc
378 bytes
Rename
Delete
md5.pyo
378 bytes
Rename
Delete
mhlib.py
32.65 KB
Rename
Delete
mhlib.pyc
32.99 KB
Rename
Delete
mhlib.pyo
32.99 KB
Rename
Delete
mimetools.py
7.00 KB
Rename
Delete
mimetools.pyc
8.01 KB
Rename
Delete
mimetools.pyo
8.01 KB
Rename
Delete
mimetypes.py
20.54 KB
Rename
Delete
mimetypes.pyc
18.06 KB
Rename
Delete
mimetypes.pyo
18.06 KB
Rename
Delete
mimify.py
14.67 KB
Rename
Delete
mimify.pyc
11.72 KB
Rename
Delete
mimify.pyo
11.72 KB
Rename
Delete
modulefinder.py
23.89 KB
Rename
Delete
modulefinder.pyc
18.68 KB
Rename
Delete
modulefinder.pyo
18.60 KB
Rename
Delete
multifile.py
4.71 KB
Rename
Delete
multifile.pyc
5.29 KB
Rename
Delete
multifile.pyo
5.25 KB
Rename
Delete
mutex.py
1.83 KB
Rename
Delete
mutex.pyc
2.46 KB
Rename
Delete
mutex.pyo
2.46 KB
Rename
Delete
netrc.py
5.75 KB
Rename
Delete
netrc.pyc
4.60 KB
Rename
Delete
netrc.pyo
4.60 KB
Rename
Delete
new.py
610 bytes
Rename
Delete
new.pyc
862 bytes
Rename
Delete
new.pyo
862 bytes
Rename
Delete
nntplib.py
20.97 KB
Rename
Delete
nntplib.pyc
20.55 KB
Rename
Delete
nntplib.pyo
20.55 KB
Rename
Delete
ntpath.py
18.97 KB
Rename
Delete
ntpath.pyc
12.82 KB
Rename
Delete
ntpath.pyo
12.82 KB
Rename
Delete
nturl2path.py
2.36 KB
Rename
Delete
nturl2path.pyc
1.77 KB
Rename
Delete
nturl2path.pyo
1.77 KB
Rename
Delete
numbers.py
10.08 KB
Rename
Delete
numbers.pyc
13.68 KB
Rename
Delete
numbers.pyo
13.68 KB
Rename
Delete
opcode.py
5.35 KB
Rename
Delete
opcode.pyc
6.00 KB
Rename
Delete
opcode.pyo
6.00 KB
Rename
Delete
optparse.py
59.77 KB
Rename
Delete
optparse.pyc
52.63 KB
Rename
Delete
optparse.pyo
52.55 KB
Rename
Delete
os.py
25.30 KB
Rename
Delete
os.pyc
25.09 KB
Rename
Delete
os.pyo
25.09 KB
Rename
Delete
os2emxpath.py
4.53 KB
Rename
Delete
os2emxpath.pyc
4.42 KB
Rename
Delete
os2emxpath.pyo
4.42 KB
Rename
Delete
pdb.doc
7.73 KB
Rename
Delete
pdb.py
45.02 KB
Rename
Delete
pdb.pyc
42.65 KB
Rename
Delete
pdb.pyo
42.65 KB
Rename
Delete
pickle.py
44.42 KB
Rename
Delete
pickle.pyc
37.66 KB
Rename
Delete
pickle.pyo
37.46 KB
Rename
Delete
pickletools.py
72.78 KB
Rename
Delete
pickletools.pyc
55.70 KB
Rename
Delete
pickletools.pyo
54.85 KB
Rename
Delete
pipes.py
9.36 KB
Rename
Delete
pipes.pyc
9.09 KB
Rename
Delete
pipes.pyo
9.09 KB
Rename
Delete
pkgutil.py
19.77 KB
Rename
Delete
pkgutil.pyc
18.51 KB
Rename
Delete
pkgutil.pyo
18.51 KB
Rename
Delete
platform.py
51.56 KB
Rename
Delete
platform.pyc
37.08 KB
Rename
Delete
platform.pyo
37.08 KB
Rename
Delete
plistlib.py
15.44 KB
Rename
Delete
plistlib.pyc
19.50 KB
Rename
Delete
plistlib.pyo
19.41 KB
Rename
Delete
popen2.py
8.22 KB
Rename
Delete
popen2.pyc
8.81 KB
Rename
Delete
popen2.pyo
8.77 KB
Rename
Delete
poplib.py
12.52 KB
Rename
Delete
poplib.pyc
13.03 KB
Rename
Delete
poplib.pyo
13.03 KB
Rename
Delete
posixfile.py
7.82 KB
Rename
Delete
posixfile.pyc
7.47 KB
Rename
Delete
posixfile.pyo
7.47 KB
Rename
Delete
posixpath.py
13.96 KB
Rename
Delete
posixpath.pyc
11.19 KB
Rename
Delete
posixpath.pyo
11.19 KB
Rename
Delete
pprint.py
11.50 KB
Rename
Delete
pprint.pyc
9.96 KB
Rename
Delete
pprint.pyo
9.78 KB
Rename
Delete
profile.py
22.25 KB
Rename
Delete
profile.pyc
16.07 KB
Rename
Delete
profile.pyo
15.83 KB
Rename
Delete
pstats.py
26.09 KB
Rename
Delete
pstats.pyc
24.43 KB
Rename
Delete
pstats.pyo
24.43 KB
Rename
Delete
pty.py
4.94 KB
Rename
Delete
pty.pyc
4.85 KB
Rename
Delete
pty.pyo
4.85 KB
Rename
Delete
py_compile.py
5.80 KB
Rename
Delete
py_compile.pyc
6.28 KB
Rename
Delete
py_compile.pyo
6.28 KB
Rename
Delete
pyclbr.py
13.07 KB
Rename
Delete
pyclbr.pyc
9.42 KB
Rename
Delete
pyclbr.pyo
9.42 KB
Rename
Delete
pydoc.py
93.50 KB
Rename
Delete
pydoc.pyc
90.18 KB
Rename
Delete
pydoc.pyo
90.12 KB
Rename
Delete
quopri.py
6.80 KB
Rename
Delete
quopri.pyc
6.42 KB
Rename
Delete
quopri.pyo
6.42 KB
Rename
Delete
random.py
31.70 KB
Rename
Delete
random.pyc
25.10 KB
Rename
Delete
random.pyo
25.10 KB
Rename
Delete
re.py
13.11 KB
Rename
Delete
re.pyc
13.10 KB
Rename
Delete
re.pyo
13.10 KB
Rename
Delete
repr.py
4.20 KB
Rename
Delete
repr.pyc
5.26 KB
Rename
Delete
repr.pyo
5.26 KB
Rename
Delete
rexec.py
19.68 KB
Rename
Delete
rexec.pyc
23.25 KB
Rename
Delete
rexec.pyo
23.25 KB
Rename
Delete
rfc822.py
32.76 KB
Rename
Delete
rfc822.pyc
31.07 KB
Rename
Delete
rfc822.pyo
31.07 KB
Rename
Delete
rlcompleter.py
5.85 KB
Rename
Delete
rlcompleter.pyc
5.94 KB
Rename
Delete
rlcompleter.pyo
5.94 KB
Rename
Delete
robotparser.py
7.51 KB
Rename
Delete
robotparser.pyc
7.82 KB
Rename
Delete
robotparser.pyo
7.82 KB
Rename
Delete
runpy.py
10.82 KB
Rename
Delete
runpy.pyc
8.60 KB
Rename
Delete
runpy.pyo
8.60 KB
Rename
Delete
sched.py
4.97 KB
Rename
Delete
sched.pyc
4.88 KB
Rename
Delete
sched.pyo
4.88 KB
Rename
Delete
sets.py
18.60 KB
Rename
Delete
sets.pyc
16.50 KB
Rename
Delete
sets.pyo
16.50 KB
Rename
Delete
sgmllib.py
17.46 KB
Rename
Delete
sgmllib.pyc
15.07 KB
Rename
Delete
sgmllib.pyo
15.07 KB
Rename
Delete
sha.py
393 bytes
Rename
Delete
sha.pyc
421 bytes
Rename
Delete
sha.pyo
421 bytes
Rename
Delete
shelve.py
7.99 KB
Rename
Delete
shelve.pyc
10.02 KB
Rename
Delete
shelve.pyo
10.02 KB
Rename
Delete
shlex.py
10.90 KB
Rename
Delete
shlex.pyc
7.38 KB
Rename
Delete
shlex.pyo
7.38 KB
Rename
Delete
shutil.py
19.41 KB
Rename
Delete
shutil.pyc
18.81 KB
Rename
Delete
shutil.pyo
18.81 KB
Rename
Delete
site.py
20.80 KB
Rename
Delete
site.pyc
20.30 KB
Rename
Delete
site.pyo
20.30 KB
Rename
Delete
smtpd.py
18.11 KB
Rename
Delete
smtpd.pyc
15.51 KB
Rename
Delete
smtpd.pyo
15.51 KB
Rename
Delete
smtplib.py
31.38 KB
Rename
Delete
smtplib.pyc
29.59 KB
Rename
Delete
smtplib.pyo
29.59 KB
Rename
Delete
sndhdr.py
5.83 KB
Rename
Delete
sndhdr.pyc
7.19 KB
Rename
Delete
sndhdr.pyo
7.19 KB
Rename
Delete
socket.py
20.13 KB
Rename
Delete
socket.pyc
15.77 KB
Rename
Delete
socket.pyo
15.69 KB
Rename
Delete
sre.py
384 bytes
Rename
Delete
sre.pyc
519 bytes
Rename
Delete
sre.pyo
519 bytes
Rename
Delete
sre_compile.py
19.36 KB
Rename
Delete
sre_compile.pyc
12.27 KB
Rename
Delete
sre_compile.pyo
12.11 KB
Rename
Delete
sre_constants.py
7.03 KB
Rename
Delete
sre_constants.pyc
6.05 KB
Rename
Delete
sre_constants.pyo
6.05 KB
Rename
Delete
sre_parse.py
29.98 KB
Rename
Delete
sre_parse.pyc
20.66 KB
Rename
Delete
sre_parse.pyo
20.66 KB
Rename
Delete
ssl.py
38.39 KB
Rename
Delete
ssl.pyc
31.95 KB
Rename
Delete
ssl.pyo
31.95 KB
Rename
Delete
stat.py
1.80 KB
Rename
Delete
stat.pyc
2.69 KB
Rename
Delete
stat.pyo
2.69 KB
Rename
Delete
statvfs.py
898 bytes
Rename
Delete
statvfs.pyc
620 bytes
Rename
Delete
statvfs.pyo
620 bytes
Rename
Delete
string.py
21.04 KB
Rename
Delete
string.pyc
19.98 KB
Rename
Delete
string.pyo
19.98 KB
Rename
Delete
stringold.py
12.16 KB
Rename
Delete
stringold.pyc
12.25 KB
Rename
Delete
stringold.pyo
12.25 KB
Rename
Delete
stringprep.py
13.21 KB
Rename
Delete
stringprep.pyc
14.15 KB
Rename
Delete
stringprep.pyo
14.08 KB
Rename
Delete
struct.py
82 bytes
Rename
Delete
struct.pyc
239 bytes
Rename
Delete
struct.pyo
239 bytes
Rename
Delete
subprocess.py
49.34 KB
Rename
Delete
subprocess.pyc
31.64 KB
Rename
Delete
subprocess.pyo
31.64 KB
Rename
Delete
sunau.py
16.82 KB
Rename
Delete
sunau.pyc
17.96 KB
Rename
Delete
sunau.pyo
17.96 KB
Rename
Delete
sunaudio.py
1.37 KB
Rename
Delete
sunaudio.pyc
1.94 KB
Rename
Delete
sunaudio.pyo
1.94 KB
Rename
Delete
symbol.py
2.01 KB
Rename
Delete
symbol.pyc
2.96 KB
Rename
Delete
symbol.pyo
2.96 KB
Rename
Delete
symtable.py
7.26 KB
Rename
Delete
symtable.pyc
11.51 KB
Rename
Delete
symtable.pyo
11.38 KB
Rename
Delete
sysconfig.py
22.32 KB
Rename
Delete
sysconfig.pyc
17.40 KB
Rename
Delete
sysconfig.pyo
17.40 KB
Rename
Delete
tabnanny.py
11.07 KB
Rename
Delete
tabnanny.pyc
8.05 KB
Rename
Delete
tabnanny.pyo
8.05 KB
Rename
Delete
tarfile.py
88.53 KB
Rename
Delete
tarfile.pyc
74.41 KB
Rename
Delete
tarfile.pyo
74.41 KB
Rename
Delete
telnetlib.py
26.40 KB
Rename
Delete
telnetlib.pyc
22.61 KB
Rename
Delete
telnetlib.pyo
22.61 KB
Rename
Delete
tempfile.py
19.09 KB
Rename
Delete
tempfile.pyc
19.87 KB
Rename
Delete
tempfile.pyo
19.87 KB
Rename
Delete
textwrap.py
16.88 KB
Rename
Delete
textwrap.pyc
11.81 KB
Rename
Delete
textwrap.pyo
11.72 KB
Rename
Delete
this.py
1002 bytes
Rename
Delete
this.pyc
1.19 KB
Rename
Delete
this.pyo
1.19 KB
Rename
Delete
threading.py
46.27 KB
Rename
Delete
threading.pyc
41.72 KB
Rename
Delete
threading.pyo
39.60 KB
Rename
Delete
timeit.py
12.49 KB
Rename
Delete
timeit.pyc
11.90 KB
Rename
Delete
timeit.pyo
11.90 KB
Rename
Delete
toaiff.py
3.07 KB
Rename
Delete
toaiff.pyc
3.03 KB
Rename
Delete
toaiff.pyo
3.03 KB
Rename
Delete
token.py
2.85 KB
Rename
Delete
token.pyc
3.73 KB
Rename
Delete
token.pyo
3.73 KB
Rename
Delete
tokenize.py
17.07 KB
Rename
Delete
tokenize.pyc
14.17 KB
Rename
Delete
tokenize.pyo
14.11 KB
Rename
Delete
trace.py
29.19 KB
Rename
Delete
trace.pyc
22.26 KB
Rename
Delete
trace.pyo
22.20 KB
Rename
Delete
traceback.py
11.02 KB
Rename
Delete
traceback.pyc
11.41 KB
Rename
Delete
traceback.pyo
11.41 KB
Rename
Delete
tty.py
879 bytes
Rename
Delete
tty.pyc
1.29 KB
Rename
Delete
tty.pyo
1.29 KB
Rename
Delete
types.py
2.04 KB
Rename
Delete
types.pyc
2.66 KB
Rename
Delete
types.pyo
2.66 KB
Rename
Delete
urllib.py
58.82 KB
Rename
Delete
urllib.pyc
50.04 KB
Rename
Delete
urllib.pyo
49.95 KB
Rename
Delete
urllib2.py
51.31 KB
Rename
Delete
urllib2.pyc
46.19 KB
Rename
Delete
urllib2.pyo
46.10 KB
Rename
Delete
urlparse.py
19.98 KB
Rename
Delete
urlparse.pyc
17.59 KB
Rename
Delete
urlparse.pyo
17.59 KB
Rename
Delete
user.py
1.59 KB
Rename
Delete
user.pyc
1.68 KB
Rename
Delete
user.pyo
1.68 KB
Rename
Delete
uu.py
6.54 KB
Rename
Delete
uu.pyc
4.29 KB
Rename
Delete
uu.pyo
4.29 KB
Rename
Delete
uuid.py
22.98 KB
Rename
Delete
uuid.pyc
22.82 KB
Rename
Delete
uuid.pyo
22.71 KB
Rename
Delete
warnings.py
14.48 KB
Rename
Delete
warnings.pyc
13.19 KB
Rename
Delete
warnings.pyo
12.42 KB
Rename
Delete
wave.py
18.15 KB
Rename
Delete
wave.pyc
19.54 KB
Rename
Delete
wave.pyo
19.40 KB
Rename
Delete
weakref.py
14.48 KB
Rename
Delete
weakref.pyc
16.06 KB
Rename
Delete
weakref.pyo
16.06 KB
Rename
Delete
webbrowser.py
22.19 KB
Rename
Delete
webbrowser.pyc
19.29 KB
Rename
Delete
webbrowser.pyo
19.24 KB
Rename
Delete
whichdb.py
3.30 KB
Rename
Delete
whichdb.pyc
2.19 KB
Rename
Delete
whichdb.pyo
2.19 KB
Rename
Delete
wsgiref.egg-info
187 bytes
Rename
Delete
xdrlib.py
5.93 KB
Rename
Delete
xdrlib.pyc
9.67 KB
Rename
Delete
xdrlib.pyo
9.67 KB
Rename
Delete
xmllib.py
34.05 KB
Rename
Delete
xmllib.pyc
26.22 KB
Rename
Delete
xmllib.pyo
26.22 KB
Rename
Delete
xmlrpclib.py
50.91 KB
Rename
Delete
xmlrpclib.pyc
43.07 KB
Rename
Delete
xmlrpclib.pyo
42.89 KB
Rename
Delete
zipfile.py
58.08 KB
Rename
Delete
zipfile.pyc
41.15 KB
Rename
Delete
zipfile.pyo
41.15 KB
Rename
Delete
"""Open an arbitrary URL. See the following document for more info on URLs: "Names and Addresses, URIs, URLs, URNs, URCs", at http://www.w3.org/pub/WWW/Addressing/Overview.html See also the HTTP spec (from which the error codes are derived): "HTTP - Hypertext Transfer Protocol", at http://www.w3.org/pub/WWW/Protocols/ Related standards and specs: - RFC1808: the "relative URL" spec. (authoritative status) - RFC1738 - the "URL standard". (authoritative status) - RFC1630 - the "URI spec". (informational status) The object returned by URLopener().open(file) will differ per protocol. All you know is that is has methods read(), readline(), readlines(), fileno(), close() and info(). The read*(), fileno() and close() methods work like those of open files. The info() method returns a mimetools.Message object which can be used to query various info about the object, if available. (mimetools.Message objects are queried with the getheader() method.) """ import string import socket import os import time import sys import base64 import re from urlparse import urljoin as basejoin __all__ = ["urlopen", "URLopener", "FancyURLopener", "urlretrieve", "urlcleanup", "quote", "quote_plus", "unquote", "unquote_plus", "urlencode", "url2pathname", "pathname2url", "splittag", "localhost", "thishost", "ftperrors", "basejoin", "unwrap", "splittype", "splithost", "splituser", "splitpasswd", "splitport", "splitnport", "splitquery", "splitattr", "splitvalue", "getproxies"] __version__ = '1.17' # XXX This version is not always updated :-( MAXFTPCACHE = 10 # Trim the ftp cache beyond this size # Helper for non-unix systems if os.name == 'nt': from nturl2path import url2pathname, pathname2url elif os.name == 'riscos': from rourl2path import url2pathname, pathname2url else: def url2pathname(pathname): """OS-specific conversion from a relative URL of the 'file' scheme to a file system path; not recommended for general use.""" return unquote(pathname) def pathname2url(pathname): """OS-specific conversion from a file system path to a relative URL of the 'file' scheme; not recommended for general use.""" return quote(pathname) # This really consists of two pieces: # (1) a class which handles opening of all sorts of URLs # (plus assorted utilities etc.) # (2) a set of functions for parsing URLs # XXX Should these be separated out into different modules? # Shortcut for basic usage _urlopener = None def urlopen(url, data=None, proxies=None, context=None): """Create a file-like object for the specified URL to read from.""" from warnings import warnpy3k warnpy3k("urllib.urlopen() has been removed in Python 3.0 in " "favor of urllib2.urlopen()", stacklevel=2) global _urlopener if proxies is not None or context is not None: opener = FancyURLopener(proxies=proxies, context=context) elif not _urlopener: opener = FancyURLopener() _urlopener = opener else: opener = _urlopener if data is None: return opener.open(url) else: return opener.open(url, data) def urlretrieve(url, filename=None, reporthook=None, data=None, context=None): global _urlopener if context is not None: opener = FancyURLopener(context=context) elif not _urlopener: _urlopener = opener = FancyURLopener() else: opener = _urlopener return opener.retrieve(url, filename, reporthook, data) def urlcleanup(): if _urlopener: _urlopener.cleanup() _safe_quoters.clear() ftpcache.clear() # check for SSL try: import ssl except: _have_ssl = False else: _have_ssl = True # exception raised when downloaded size does not match content-length class ContentTooShortError(IOError): def __init__(self, message, content): IOError.__init__(self, message) self.content = content ftpcache = {} class URLopener: """Class to open URLs. This is a class rather than just a subroutine because we may need more than one set of global protocol-specific options. Note -- this is a base class for those who don't want the automatic handling of errors type 302 (relocated) and 401 (authorization needed).""" __tempfiles = None version = "Python-urllib/%s" % __version__ # Constructor def __init__(self, proxies=None, context=None, **x509): if proxies is None: proxies = getproxies() assert hasattr(proxies, 'has_key'), "proxies must be a mapping" self.proxies = proxies self.key_file = x509.get('key_file') self.cert_file = x509.get('cert_file') self.context = context self.addheaders = [('User-Agent', self.version), ('Accept', '*/*')] self.__tempfiles = [] self.__unlink = os.unlink # See cleanup() self.tempcache = None # Undocumented feature: if you assign {} to tempcache, # it is used to cache files retrieved with # self.retrieve(). This is not enabled by default # since it does not work for changing documents (and I # haven't got the logic to check expiration headers # yet). self.ftpcache = ftpcache # Undocumented feature: you can use a different # ftp cache by assigning to the .ftpcache member; # in case you want logically independent URL openers # XXX This is not threadsafe. Bah. def __del__(self): self.close() def close(self): self.cleanup() def cleanup(self): # This code sometimes runs when the rest of this module # has already been deleted, so it can't use any globals # or import anything. if self.__tempfiles: for file in self.__tempfiles: try: self.__unlink(file) except OSError: pass del self.__tempfiles[:] if self.tempcache: self.tempcache.clear() def addheader(self, *args): """Add a header to be used by the HTTP interface only e.g. u.addheader('Accept', 'sound/basic')""" self.addheaders.append(args) # External interface def open(self, fullurl, data=None): """Use URLopener().open(file) instead of open(file, 'r').""" fullurl = unwrap(toBytes(fullurl)) # percent encode url, fixing lame server errors for e.g, like space # within url paths. fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]|") if self.tempcache and fullurl in self.tempcache: filename, headers = self.tempcache[fullurl] fp = open(filename, 'rb') return addinfourl(fp, headers, fullurl) urltype, url = splittype(fullurl) if not urltype: urltype = 'file' if urltype in self.proxies: proxy = self.proxies[urltype] urltype, proxyhost = splittype(proxy) host, selector = splithost(proxyhost) url = (host, fullurl) # Signal special case to open_*() else: proxy = None name = 'open_' + urltype self.type = urltype name = name.replace('-', '_') # bpo-35907: disallow the file reading with the type not allowed if not hasattr(self, name) or name == 'open_local_file': if proxy: return self.open_unknown_proxy(proxy, fullurl, data) else: return self.open_unknown(fullurl, data) try: if data is None: return getattr(self, name)(url) else: return getattr(self, name)(url, data) except socket.error, msg: raise IOError, ('socket error', msg), sys.exc_info()[2] def open_unknown(self, fullurl, data=None): """Overridable interface to open unknown URL type.""" type, url = splittype(fullurl) raise IOError, ('url error', 'unknown url type', type) def open_unknown_proxy(self, proxy, fullurl, data=None): """Overridable interface to open unknown URL type.""" type, url = splittype(fullurl) raise IOError, ('url error', 'invalid proxy for %s' % type, proxy) # External interface def retrieve(self, url, filename=None, reporthook=None, data=None): """retrieve(url) returns (filename, headers) for a local object or (tempfilename, headers) for a remote object.""" url = unwrap(toBytes(url)) if self.tempcache and url in self.tempcache: return self.tempcache[url] type, url1 = splittype(url) if filename is None and (not type or type == 'file'): try: fp = self.open_local_file(url1) hdrs = fp.info() fp.close() return url2pathname(splithost(url1)[1]), hdrs except IOError: pass fp = self.open(url, data) try: headers = fp.info() if filename: tfp = open(filename, 'wb') else: import tempfile garbage, path = splittype(url) garbage, path = splithost(path or "") path, garbage = splitquery(path or "") path, garbage = splitattr(path or "") suffix = os.path.splitext(path)[1] (fd, filename) = tempfile.mkstemp(suffix) self.__tempfiles.append(filename) tfp = os.fdopen(fd, 'wb') try: result = filename, headers if self.tempcache is not None: self.tempcache[url] = result bs = 1024*8 size = -1 read = 0 blocknum = 0 if "content-length" in headers: size = int(headers["Content-Length"]) if reporthook: reporthook(blocknum, bs, size) while 1: block = fp.read(bs) if block == "": break read += len(block) tfp.write(block) blocknum += 1 if reporthook: reporthook(blocknum, bs, size) finally: tfp.close() finally: fp.close() # raise exception if actual size does not match content-length header if size >= 0 and read < size: raise ContentTooShortError("retrieval incomplete: got only %i out " "of %i bytes" % (read, size), result) return result # Each method named open_<type> knows how to open that type of URL def open_http(self, url, data=None): """Use HTTP protocol.""" import httplib user_passwd = None proxy_passwd= None if isinstance(url, str): host, selector = splithost(url) if host: user_passwd, host = splituser(host) host = unquote(host) realhost = host else: host, selector = url # check whether the proxy contains authorization information proxy_passwd, host = splituser(host) # now we proceed with the url we want to obtain urltype, rest = splittype(selector) url = rest user_passwd = None if urltype.lower() != 'http': realhost = None else: realhost, rest = splithost(rest) if realhost: user_passwd, realhost = splituser(realhost) if user_passwd: selector = "%s://%s%s" % (urltype, realhost, rest) if proxy_bypass(realhost): host = realhost #print "proxy via http:", host, selector if not host: raise IOError, ('http error', 'no host given') if proxy_passwd: proxy_passwd = unquote(proxy_passwd) proxy_auth = base64.b64encode(proxy_passwd).strip() else: proxy_auth = None if user_passwd: user_passwd = unquote(user_passwd) auth = base64.b64encode(user_passwd).strip() else: auth = None h = httplib.HTTP(host) if data is not None: h.putrequest('POST', selector) h.putheader('Content-Type', 'application/x-www-form-urlencoded') h.putheader('Content-Length', '%d' % len(data)) else: h.putrequest('GET', selector) if proxy_auth: h.putheader('Proxy-Authorization', 'Basic %s' % proxy_auth) if auth: h.putheader('Authorization', 'Basic %s' % auth) if realhost: h.putheader('Host', realhost) for args in self.addheaders: h.putheader(*args) h.endheaders(data) errcode, errmsg, headers = h.getreply() fp = h.getfile() if errcode == -1: if fp: fp.close() # something went wrong with the HTTP status line raise IOError, ('http protocol error', 0, 'got a bad status line', None) # According to RFC 2616, "2xx" code indicates that the client's # request was successfully received, understood, and accepted. if (200 <= errcode < 300): return addinfourl(fp, headers, "http:" + url, errcode) else: if data is None: return self.http_error(url, fp, errcode, errmsg, headers) else: return self.http_error(url, fp, errcode, errmsg, headers, data) def http_error(self, url, fp, errcode, errmsg, headers, data=None): """Handle http errors. Derived class can override this, or provide specific handlers named http_error_DDD where DDD is the 3-digit error code.""" # First check if there's a specific handler for this error name = 'http_error_%d' % errcode if hasattr(self, name): method = getattr(self, name) if data is None: result = method(url, fp, errcode, errmsg, headers) else: result = method(url, fp, errcode, errmsg, headers, data) if result: return result return self.http_error_default(url, fp, errcode, errmsg, headers) def http_error_default(self, url, fp, errcode, errmsg, headers): """Default error handler: close the connection and raise IOError.""" fp.close() raise IOError, ('http error', errcode, errmsg, headers) if _have_ssl: def open_https(self, url, data=None): """Use HTTPS protocol.""" import httplib user_passwd = None proxy_passwd = None if isinstance(url, str): host, selector = splithost(url) if host: user_passwd, host = splituser(host) host = unquote(host) realhost = host else: host, selector = url # here, we determine, whether the proxy contains authorization information proxy_passwd, host = splituser(host) urltype, rest = splittype(selector) url = rest user_passwd = None if urltype.lower() != 'https': realhost = None else: realhost, rest = splithost(rest) if realhost: user_passwd, realhost = splituser(realhost) if user_passwd: selector = "%s://%s%s" % (urltype, realhost, rest) #print "proxy via https:", host, selector if not host: raise IOError, ('https error', 'no host given') if proxy_passwd: proxy_passwd = unquote(proxy_passwd) proxy_auth = base64.b64encode(proxy_passwd).strip() else: proxy_auth = None if user_passwd: user_passwd = unquote(user_passwd) auth = base64.b64encode(user_passwd).strip() else: auth = None h = httplib.HTTPS(host, 0, key_file=self.key_file, cert_file=self.cert_file, context=self.context) if data is not None: h.putrequest('POST', selector) h.putheader('Content-Type', 'application/x-www-form-urlencoded') h.putheader('Content-Length', '%d' % len(data)) else: h.putrequest('GET', selector) if proxy_auth: h.putheader('Proxy-Authorization', 'Basic %s' % proxy_auth) if auth: h.putheader('Authorization', 'Basic %s' % auth) if realhost: h.putheader('Host', realhost) for args in self.addheaders: h.putheader(*args) h.endheaders(data) errcode, errmsg, headers = h.getreply() fp = h.getfile() if errcode == -1: if fp: fp.close() # something went wrong with the HTTP status line raise IOError, ('http protocol error', 0, 'got a bad status line', None) # According to RFC 2616, "2xx" code indicates that the client's # request was successfully received, understood, and accepted. if (200 <= errcode < 300): return addinfourl(fp, headers, "https:" + url, errcode) else: if data is None: return self.http_error(url, fp, errcode, errmsg, headers) else: return self.http_error(url, fp, errcode, errmsg, headers, data) def open_file(self, url): """Use local file or FTP depending on form of URL.""" if not isinstance(url, str): raise IOError, ('file error', 'proxy support for file protocol currently not implemented') if url[:2] == '//' and url[2:3] != '/' and url[2:12].lower() != 'localhost/': return self.open_ftp(url) else: return self.open_local_file(url) def open_local_file(self, url): """Use local file.""" import mimetypes, mimetools, email.utils try: from cStringIO import StringIO except ImportError: from StringIO import StringIO host, file = splithost(url) localname = url2pathname(file) try: stats = os.stat(localname) except OSError, e: raise IOError(e.errno, e.strerror, e.filename) size = stats.st_size modified = email.utils.formatdate(stats.st_mtime, usegmt=True) mtype = mimetypes.guess_type(url)[0] headers = mimetools.Message(StringIO( 'Content-Type: %s\nContent-Length: %d\nLast-modified: %s\n' % (mtype or 'text/plain', size, modified))) if not host: urlfile = file if file[:1] == '/': urlfile = 'file://' + file elif file[:2] == './': raise ValueError("local file url may start with / or file:. Unknown url of type: %s" % url) return addinfourl(open(localname, 'rb'), headers, urlfile) host, port = splitport(host) if not port \ and socket.gethostbyname(host) in (localhost(), thishost()): urlfile = file if file[:1] == '/': urlfile = 'file://' + file return addinfourl(open(localname, 'rb'), headers, urlfile) raise IOError, ('local file error', 'not on local host') def open_ftp(self, url): """Use FTP protocol.""" if not isinstance(url, str): raise IOError, ('ftp error', 'proxy support for ftp protocol currently not implemented') import mimetypes, mimetools try: from cStringIO import StringIO except ImportError: from StringIO import StringIO host, path = splithost(url) if not host: raise IOError, ('ftp error', 'no host given') host, port = splitport(host) user, host = splituser(host) if user: user, passwd = splitpasswd(user) else: passwd = None host = unquote(host) user = user or '' passwd = passwd or '' host = socket.gethostbyname(host) if not port: import ftplib port = ftplib.FTP_PORT else: port = int(port) path, attrs = splitattr(path) path = unquote(path) dirs = path.split('/') dirs, file = dirs[:-1], dirs[-1] if dirs and not dirs[0]: dirs = dirs[1:] if dirs and not dirs[0]: dirs[0] = '/' key = user, host, port, '/'.join(dirs) # XXX thread unsafe! if len(self.ftpcache) > MAXFTPCACHE: # Prune the cache, rather arbitrarily for k in self.ftpcache.keys(): if k != key: v = self.ftpcache[k] del self.ftpcache[k] v.close() try: if not key in self.ftpcache: self.ftpcache[key] = \ ftpwrapper(user, passwd, host, port, dirs) if not file: type = 'D' else: type = 'I' for attr in attrs: attr, value = splitvalue(attr) if attr.lower() == 'type' and \ value in ('a', 'A', 'i', 'I', 'd', 'D'): type = value.upper() (fp, retrlen) = self.ftpcache[key].retrfile(file, type) mtype = mimetypes.guess_type("ftp:" + url)[0] headers = "" if mtype: headers += "Content-Type: %s\n" % mtype if retrlen is not None and retrlen >= 0: headers += "Content-Length: %d\n" % retrlen headers = mimetools.Message(StringIO(headers)) return addinfourl(fp, headers, "ftp:" + url) except ftperrors(), msg: raise IOError, ('ftp error', msg), sys.exc_info()[2] def open_data(self, url, data=None): """Use "data" URL.""" if not isinstance(url, str): raise IOError, ('data error', 'proxy support for data protocol currently not implemented') # ignore POSTed data # # syntax of data URLs: # dataurl := "data:" [ mediatype ] [ ";base64" ] "," data # mediatype := [ type "/" subtype ] *( ";" parameter ) # data := *urlchar # parameter := attribute "=" value import mimetools try: from cStringIO import StringIO except ImportError: from StringIO import StringIO try: [type, data] = url.split(',', 1) except ValueError: raise IOError, ('data error', 'bad data URL') if not type: type = 'text/plain;charset=US-ASCII' semi = type.rfind(';') if semi >= 0 and '=' not in type[semi:]: encoding = type[semi+1:] type = type[:semi] else: encoding = '' msg = [] msg.append('Date: %s'%time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime(time.time()))) msg.append('Content-type: %s' % type) if encoding == 'base64': data = base64.decodestring(data) else: data = unquote(data) msg.append('Content-Length: %d' % len(data)) msg.append('') msg.append(data) msg = '\n'.join(msg) f = StringIO(msg) headers = mimetools.Message(f, 0) #f.fileno = None # needed for addinfourl return addinfourl(f, headers, url) class FancyURLopener(URLopener): """Derived class with handlers for errors we can handle (perhaps).""" def __init__(self, *args, **kwargs): URLopener.__init__(self, *args, **kwargs) self.auth_cache = {} self.tries = 0 self.maxtries = 10 def http_error_default(self, url, fp, errcode, errmsg, headers): """Default error handling -- don't raise an exception.""" return addinfourl(fp, headers, "http:" + url, errcode) def http_error_302(self, url, fp, errcode, errmsg, headers, data=None): """Error 302 -- relocated (temporarily).""" self.tries += 1 try: if self.maxtries and self.tries >= self.maxtries: if hasattr(self, "http_error_500"): meth = self.http_error_500 else: meth = self.http_error_default return meth(url, fp, 500, "Internal Server Error: Redirect Recursion", headers) result = self.redirect_internal(url, fp, errcode, errmsg, headers, data) return result finally: self.tries = 0 def redirect_internal(self, url, fp, errcode, errmsg, headers, data): if 'location' in headers: newurl = headers['location'] elif 'uri' in headers: newurl = headers['uri'] else: return fp.close() # In case the server sent a relative URL, join with original: newurl = basejoin(self.type + ":" + url, newurl) # For security reasons we do not allow redirects to protocols # other than HTTP, HTTPS or FTP. newurl_lower = newurl.lower() if not (newurl_lower.startswith('http://') or newurl_lower.startswith('https://') or newurl_lower.startswith('ftp://')): raise IOError('redirect error', errcode, errmsg + " - Redirection to url '%s' is not allowed" % newurl, headers) return self.open(newurl) def http_error_301(self, url, fp, errcode, errmsg, headers, data=None): """Error 301 -- also relocated (permanently).""" return self.http_error_302(url, fp, errcode, errmsg, headers, data) def http_error_303(self, url, fp, errcode, errmsg, headers, data=None): """Error 303 -- also relocated (essentially identical to 302).""" return self.http_error_302(url, fp, errcode, errmsg, headers, data) def http_error_307(self, url, fp, errcode, errmsg, headers, data=None): """Error 307 -- relocated, but turn POST into error.""" if data is None: return self.http_error_302(url, fp, errcode, errmsg, headers, data) else: return self.http_error_default(url, fp, errcode, errmsg, headers) def http_error_401(self, url, fp, errcode, errmsg, headers, data=None): """Error 401 -- authentication required. This function supports Basic authentication only.""" if not 'www-authenticate' in headers: URLopener.http_error_default(self, url, fp, errcode, errmsg, headers) stuff = headers['www-authenticate'] import re match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff) if not match: URLopener.http_error_default(self, url, fp, errcode, errmsg, headers) scheme, realm = match.groups() if scheme.lower() != 'basic': URLopener.http_error_default(self, url, fp, errcode, errmsg, headers) name = 'retry_' + self.type + '_basic_auth' if data is None: return getattr(self,name)(url, realm) else: return getattr(self,name)(url, realm, data) def http_error_407(self, url, fp, errcode, errmsg, headers, data=None): """Error 407 -- proxy authentication required. This function supports Basic authentication only.""" if not 'proxy-authenticate' in headers: URLopener.http_error_default(self, url, fp, errcode, errmsg, headers) stuff = headers['proxy-authenticate'] import re match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff) if not match: URLopener.http_error_default(self, url, fp, errcode, errmsg, headers) scheme, realm = match.groups() if scheme.lower() != 'basic': URLopener.http_error_default(self, url, fp, errcode, errmsg, headers) name = 'retry_proxy_' + self.type + '_basic_auth' if data is None: return getattr(self,name)(url, realm) else: return getattr(self,name)(url, realm, data) def retry_proxy_http_basic_auth(self, url, realm, data=None): host, selector = splithost(url) newurl = 'http://' + host + selector proxy = self.proxies['http'] urltype, proxyhost = splittype(proxy) proxyhost, proxyselector = splithost(proxyhost) i = proxyhost.find('@') + 1 proxyhost = proxyhost[i:] user, passwd = self.get_user_passwd(proxyhost, realm, i) if not (user or passwd): return None proxyhost = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + proxyhost self.proxies['http'] = 'http://' + proxyhost + proxyselector if data is None: return self.open(newurl) else: return self.open(newurl, data) def retry_proxy_https_basic_auth(self, url, realm, data=None): host, selector = splithost(url) newurl = 'https://' + host + selector proxy = self.proxies['https'] urltype, proxyhost = splittype(proxy) proxyhost, proxyselector = splithost(proxyhost) i = proxyhost.find('@') + 1 proxyhost = proxyhost[i:] user, passwd = self.get_user_passwd(proxyhost, realm, i) if not (user or passwd): return None proxyhost = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + proxyhost self.proxies['https'] = 'https://' + proxyhost + proxyselector if data is None: return self.open(newurl) else: return self.open(newurl, data) def retry_http_basic_auth(self, url, realm, data=None): host, selector = splithost(url) i = host.find('@') + 1 host = host[i:] user, passwd = self.get_user_passwd(host, realm, i) if not (user or passwd): return None host = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + host newurl = 'http://' + host + selector if data is None: return self.open(newurl) else: return self.open(newurl, data) def retry_https_basic_auth(self, url, realm, data=None): host, selector = splithost(url) i = host.find('@') + 1 host = host[i:] user, passwd = self.get_user_passwd(host, realm, i) if not (user or passwd): return None host = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + host newurl = 'https://' + host + selector if data is None: return self.open(newurl) else: return self.open(newurl, data) def get_user_passwd(self, host, realm, clear_cache=0): key = realm + '@' + host.lower() if key in self.auth_cache: if clear_cache: del self.auth_cache[key] else: return self.auth_cache[key] user, passwd = self.prompt_user_passwd(host, realm) if user or passwd: self.auth_cache[key] = (user, passwd) return user, passwd def prompt_user_passwd(self, host, realm): """Override this in a GUI environment!""" import getpass try: user = raw_input("Enter username for %s at %s: " % (realm, host)) passwd = getpass.getpass("Enter password for %s in %s at %s: " % (user, realm, host)) return user, passwd except KeyboardInterrupt: print return None, None # Utility functions _localhost = None def localhost(): """Return the IP address of the magic hostname 'localhost'.""" global _localhost if _localhost is None: _localhost = socket.gethostbyname('localhost') return _localhost _thishost = None def thishost(): """Return the IP address of the current host.""" global _thishost if _thishost is None: try: _thishost = socket.gethostbyname(socket.gethostname()) except socket.gaierror: _thishost = socket.gethostbyname('localhost') return _thishost _ftperrors = None def ftperrors(): """Return the set of errors raised by the FTP class.""" global _ftperrors if _ftperrors is None: import ftplib _ftperrors = ftplib.all_errors return _ftperrors _noheaders = None def noheaders(): """Return an empty mimetools.Message object.""" global _noheaders if _noheaders is None: import mimetools try: from cStringIO import StringIO except ImportError: from StringIO import StringIO _noheaders = mimetools.Message(StringIO(), 0) _noheaders.fp.close() # Recycle file descriptor return _noheaders # Utility classes class ftpwrapper: """Class used by open_ftp() for cache of open FTP connections.""" def __init__(self, user, passwd, host, port, dirs, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, persistent=True): self.user = user self.passwd = passwd self.host = host self.port = port self.dirs = dirs self.timeout = timeout self.refcount = 0 self.keepalive = persistent try: self.init() except: self.close() raise def init(self): import ftplib self.busy = 0 self.ftp = ftplib.FTP() self.ftp.connect(self.host, self.port, self.timeout) self.ftp.login(self.user, self.passwd) _target = '/'.join(self.dirs) self.ftp.cwd(_target) def retrfile(self, file, type): import ftplib self.endtransfer() if type in ('d', 'D'): cmd = 'TYPE A'; isdir = 1 else: cmd = 'TYPE ' + type; isdir = 0 try: self.ftp.voidcmd(cmd) except ftplib.all_errors: self.init() self.ftp.voidcmd(cmd) conn = None if file and not isdir: # Try to retrieve as a file try: cmd = 'RETR ' + file conn, retrlen = self.ftp.ntransfercmd(cmd) except ftplib.error_perm, reason: if str(reason)[:3] != '550': raise IOError, ('ftp error', reason), sys.exc_info()[2] if not conn: # Set transfer mode to ASCII! self.ftp.voidcmd('TYPE A') # Try a directory listing. Verify that directory exists. if file: pwd = self.ftp.pwd() try: try: self.ftp.cwd(file) except ftplib.error_perm, reason: raise IOError, ('ftp error', reason), sys.exc_info()[2] finally: self.ftp.cwd(pwd) cmd = 'LIST ' + file else: cmd = 'LIST' conn, retrlen = self.ftp.ntransfercmd(cmd) self.busy = 1 ftpobj = addclosehook(conn.makefile('rb'), self.file_close) self.refcount += 1 conn.close() # Pass back both a suitably decorated object and a retrieval length return (ftpobj, retrlen) def endtransfer(self): if not self.busy: return self.busy = 0 try: self.ftp.voidresp() except ftperrors(): pass def close(self): self.keepalive = False if self.refcount <= 0: self.real_close() def file_close(self): self.endtransfer() self.refcount -= 1 if self.refcount <= 0 and not self.keepalive: self.real_close() def real_close(self): self.endtransfer() try: self.ftp.close() except ftperrors(): pass class addbase: """Base class for addinfo and addclosehook.""" def __init__(self, fp): self.fp = fp self.read = self.fp.read self.readline = self.fp.readline if hasattr(self.fp, "readlines"): self.readlines = self.fp.readlines if hasattr(self.fp, "fileno"): self.fileno = self.fp.fileno else: self.fileno = lambda: None if hasattr(self.fp, "__iter__"): self.__iter__ = self.fp.__iter__ if hasattr(self.fp, "next"): self.next = self.fp.next def __repr__(self): return '<%s at %r whose fp = %r>' % (self.__class__.__name__, id(self), self.fp) def close(self): self.read = None self.readline = None self.readlines = None self.fileno = None if self.fp: self.fp.close() self.fp = None class addclosehook(addbase): """Class to add a close hook to an open file.""" def __init__(self, fp, closehook, *hookargs): addbase.__init__(self, fp) self.closehook = closehook self.hookargs = hookargs def close(self): try: closehook = self.closehook hookargs = self.hookargs if closehook: self.closehook = None self.hookargs = None closehook(*hookargs) finally: addbase.close(self) class addinfo(addbase): """class to add an info() method to an open file.""" def __init__(self, fp, headers): addbase.__init__(self, fp) self.headers = headers def info(self): return self.headers class addinfourl(addbase): """class to add info() and geturl() methods to an open file.""" def __init__(self, fp, headers, url, code=None): addbase.__init__(self, fp) self.headers = headers self.url = url self.code = code def info(self): return self.headers def getcode(self): return self.code def geturl(self): return self.url # Utilities to parse URLs (most of these return None for missing parts): # unwrap('<URL:type://host/path>') --> 'type://host/path' # splittype('type:opaquestring') --> 'type', 'opaquestring' # splithost('//host[:port]/path') --> 'host[:port]', '/path' # splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]' # splitpasswd('user:passwd') -> 'user', 'passwd' # splitport('host:port') --> 'host', 'port' # splitquery('/path?query') --> '/path', 'query' # splittag('/path#tag') --> '/path', 'tag' # splitattr('/path;attr1=value1;attr2=value2;...') -> # '/path', ['attr1=value1', 'attr2=value2', ...] # splitvalue('attr=value') --> 'attr', 'value' # unquote('abc%20def') -> 'abc def' # quote('abc def') -> 'abc%20def') try: unicode except NameError: def _is_unicode(x): return 0 else: def _is_unicode(x): return isinstance(x, unicode) def toBytes(url): """toBytes(u"URL") --> 'URL'.""" # Most URL schemes require ASCII. If that changes, the conversion # can be relaxed if _is_unicode(url): try: url = url.encode("ASCII") except UnicodeError: raise UnicodeError("URL " + repr(url) + " contains non-ASCII characters") return url def unwrap(url): """unwrap('<URL:type://host/path>') --> 'type://host/path'.""" url = url.strip() if url[:1] == '<' and url[-1:] == '>': url = url[1:-1].strip() if url[:4] == 'URL:': url = url[4:].strip() return url _typeprog = None def splittype(url): """splittype('type:opaquestring') --> 'type', 'opaquestring'.""" global _typeprog if _typeprog is None: import re _typeprog = re.compile('^([^/:]+):') match = _typeprog.match(url) if match: scheme = match.group(1) return scheme.lower(), url[len(scheme) + 1:] return None, url _hostprog = None def splithost(url): """splithost('//host[:port]/path') --> 'host[:port]', '/path'.""" global _hostprog if _hostprog is None: _hostprog = re.compile('//([^/#?]*)(.*)', re.DOTALL) match = _hostprog.match(url) if match: host_port = match.group(1) path = match.group(2) if path and not path.startswith('/'): path = '/' + path return host_port, path return None, url _userprog = None def splituser(host): """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.""" global _userprog if _userprog is None: import re _userprog = re.compile('^(.*)@(.*)$') match = _userprog.match(host) if match: return match.group(1, 2) return None, host _passwdprog = None def splitpasswd(user): """splitpasswd('user:passwd') -> 'user', 'passwd'.""" global _passwdprog if _passwdprog is None: import re _passwdprog = re.compile('^([^:]*):(.*)$',re.S) match = _passwdprog.match(user) if match: return match.group(1, 2) return user, None # splittag('/path#tag') --> '/path', 'tag' _portprog = None def splitport(host): """splitport('host:port') --> 'host', 'port'.""" global _portprog if _portprog is None: import re _portprog = re.compile('^(.*):([0-9]*)$') match = _portprog.match(host) if match: host, port = match.groups() if port: return host, port return host, None _nportprog = None def splitnport(host, defport=-1): """Split host and port, returning numeric port. Return given default port if no ':' found; defaults to -1. Return numerical port if a valid number are found after ':'. Return None if ':' but not a valid number.""" global _nportprog if _nportprog is None: import re _nportprog = re.compile('^(.*):(.*)$') match = _nportprog.match(host) if match: host, port = match.group(1, 2) if port: try: nport = int(port) except ValueError: nport = None return host, nport return host, defport _queryprog = None def splitquery(url): """splitquery('/path?query') --> '/path', 'query'.""" global _queryprog if _queryprog is None: import re _queryprog = re.compile('^(.*)\?([^?]*)$') match = _queryprog.match(url) if match: return match.group(1, 2) return url, None _tagprog = None def splittag(url): """splittag('/path#tag') --> '/path', 'tag'.""" global _tagprog if _tagprog is None: import re _tagprog = re.compile('^(.*)#([^#]*)$') match = _tagprog.match(url) if match: return match.group(1, 2) return url, None def splitattr(url): """splitattr('/path;attr1=value1;attr2=value2;...') -> '/path', ['attr1=value1', 'attr2=value2', ...].""" words = url.split(';') return words[0], words[1:] _valueprog = None def splitvalue(attr): """splitvalue('attr=value') --> 'attr', 'value'.""" global _valueprog if _valueprog is None: import re _valueprog = re.compile('^([^=]*)=(.*)$') match = _valueprog.match(attr) if match: return match.group(1, 2) return attr, None # urlparse contains a duplicate of this method to avoid a circular import. If # you update this method, also update the copy in urlparse. This code # duplication does not exist in Python3. _hexdig = '0123456789ABCDEFabcdef' _hextochr = dict((a + b, chr(int(a + b, 16))) for a in _hexdig for b in _hexdig) _asciire = re.compile('([\x00-\x7f]+)') def unquote(s): """unquote('abc%20def') -> 'abc def'.""" if _is_unicode(s): if '%' not in s: return s bits = _asciire.split(s) res = [bits[0]] append = res.append for i in range(1, len(bits), 2): append(unquote(str(bits[i])).decode('latin1')) append(bits[i + 1]) return ''.join(res) bits = s.split('%') # fastpath if len(bits) == 1: return s res = [bits[0]] append = res.append for item in bits[1:]: try: append(_hextochr[item[:2]]) append(item[2:]) except KeyError: append('%') append(item) return ''.join(res) def unquote_plus(s): """unquote('%7e/abc+def') -> '~/abc def'""" s = s.replace('+', ' ') return unquote(s) always_safe = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' '0123456789' '_.-') _safe_map = {} for i, c in zip(xrange(256), str(bytearray(xrange(256)))): _safe_map[c] = c if (i < 128 and c in always_safe) else '%{:02X}'.format(i) _safe_quoters = {} def quote(s, safe='/'): """quote('abc def') -> 'abc%20def' Each part of a URL, e.g. the path info, the query, etc., has a different set of reserved characters that must be quoted. RFC 2396 Uniform Resource Identifiers (URI): Generic Syntax lists the following reserved characters. reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," Each of these characters is reserved in some component of a URL, but not necessarily in all of them. By default, the quote function is intended for quoting the path section of a URL. Thus, it will not encode '/'. This character is reserved, but in typical usage the quote function is being called on a path where the existing slash characters are used as reserved characters. """ # fastpath if not s: if s is None: raise TypeError('None object cannot be quoted') return s cachekey = (safe, always_safe) try: (quoter, safe) = _safe_quoters[cachekey] except KeyError: safe_map = _safe_map.copy() safe_map.update([(c, c) for c in safe]) quoter = safe_map.__getitem__ safe = always_safe + safe _safe_quoters[cachekey] = (quoter, safe) if not s.rstrip(safe): return s return ''.join(map(quoter, s)) def quote_plus(s, safe=''): """Quote the query fragment of a URL; replacing ' ' with '+'""" if ' ' in s: s = quote(s, safe + ' ') return s.replace(' ', '+') return quote(s, safe) def urlencode(query, doseq=0): """Encode a sequence of two-element tuples or dictionary into a URL query string. If any values in the query arg are sequences and doseq is true, each sequence element is converted to a separate parameter. If the query arg is a sequence of two-element tuples, the order of the parameters in the output will match the order of parameters in the input. """ if hasattr(query,"items"): # mapping objects query = query.items() else: # it's a bother at times that strings and string-like objects are # sequences... try: # non-sequence items should not work with len() # non-empty strings will fail this if len(query) and not isinstance(query[0], tuple): raise TypeError # zero-length sequences of all types will get here and succeed, # but that's a minor nit - since the original implementation # allowed empty dicts that type of behavior probably should be # preserved for consistency except TypeError: ty,va,tb = sys.exc_info() raise TypeError, "not a valid non-string sequence or mapping object", tb l = [] if not doseq: # preserve old behavior for k, v in query: k = quote_plus(str(k)) v = quote_plus(str(v)) l.append(k + '=' + v) else: for k, v in query: k = quote_plus(str(k)) if isinstance(v, str): v = quote_plus(v) l.append(k + '=' + v) elif _is_unicode(v): # is there a reasonable way to convert to ASCII? # encode generates a string, but "replace" or "ignore" # lose information and "strict" can raise UnicodeError v = quote_plus(v.encode("ASCII","replace")) l.append(k + '=' + v) else: try: # is this a sufficient test for sequence-ness? len(v) except TypeError: # not a sequence v = quote_plus(str(v)) l.append(k + '=' + v) else: # loop over the sequence for elt in v: l.append(k + '=' + quote_plus(str(elt))) return '&'.join(l) # Proxy handling def getproxies_environment(): """Return a dictionary of scheme -> proxy server URL mappings. Scan the environment for variables named <scheme>_proxy; this seems to be the standard convention. In order to prefer lowercase variables, we process the environment in two passes, first matches any and second matches only lower case proxies. If you need a different way, you can pass a proxies dictionary to the [Fancy]URLopener constructor. """ # Get all variables proxies = {} for name, value in os.environ.items(): name = name.lower() if value and name[-6:] == '_proxy': proxies[name[:-6]] = value # CVE-2016-1000110 - If we are running as CGI script, forget HTTP_PROXY # (non-all-lowercase) as it may be set from the web server by a "Proxy:" # header from the client # If "proxy" is lowercase, it will still be used thanks to the next block if 'REQUEST_METHOD' in os.environ: proxies.pop('http', None) # Get lowercase variables for name, value in os.environ.items(): if name[-6:] == '_proxy': name = name.lower() if value: proxies[name[:-6]] = value else: proxies.pop(name[:-6], None) return proxies def proxy_bypass_environment(host, proxies=None): """Test if proxies should not be used for a particular host. Checks the proxies dict for the value of no_proxy, which should be a list of comma separated DNS suffixes, or '*' for all hosts. """ if proxies is None: proxies = getproxies_environment() # don't bypass, if no_proxy isn't specified try: no_proxy = proxies['no'] except KeyError: return 0 # '*' is special case for always bypass if no_proxy == '*': return 1 # strip port off host hostonly, port = splitport(host) # check if the host ends with any of the DNS suffixes no_proxy_list = [proxy.strip() for proxy in no_proxy.split(',')] for name in no_proxy_list: if name: name = name.lstrip('.') # ignore leading dots name = re.escape(name) pattern = r'(.+\.)?%s$' % name if (re.match(pattern, hostonly, re.I) or re.match(pattern, host, re.I)): return 1 # otherwise, don't bypass return 0 if sys.platform == 'darwin': from _scproxy import _get_proxy_settings, _get_proxies def proxy_bypass_macosx_sysconf(host): """ Return True iff this host shouldn't be accessed using a proxy This function uses the MacOSX framework SystemConfiguration to fetch the proxy information. """ import re import socket from fnmatch import fnmatch hostonly, port = splitport(host) def ip2num(ipAddr): parts = ipAddr.split('.') parts = map(int, parts) if len(parts) != 4: parts = (parts + [0, 0, 0, 0])[:4] return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3] proxy_settings = _get_proxy_settings() # Check for simple host names: if '.' not in host: if proxy_settings['exclude_simple']: return True hostIP = None for value in proxy_settings.get('exceptions', ()): # Items in the list are strings like these: *.local, 169.254/16 if not value: continue m = re.match(r"(\d+(?:\.\d+)*)(/\d+)?", value) if m is not None: if hostIP is None: try: hostIP = socket.gethostbyname(hostonly) hostIP = ip2num(hostIP) except socket.error: continue base = ip2num(m.group(1)) mask = m.group(2) if mask is None: mask = 8 * (m.group(1).count('.') + 1) else: mask = int(mask[1:]) mask = 32 - mask if (hostIP >> mask) == (base >> mask): return True elif fnmatch(host, value): return True return False def getproxies_macosx_sysconf(): """Return a dictionary of scheme -> proxy server URL mappings. This function uses the MacOSX framework SystemConfiguration to fetch the proxy information. """ return _get_proxies() def proxy_bypass(host): """Return True, if a host should be bypassed. Checks proxy settings gathered from the environment, if specified, or from the MacOSX framework SystemConfiguration. """ proxies = getproxies_environment() if proxies: return proxy_bypass_environment(host, proxies) else: return proxy_bypass_macosx_sysconf(host) def getproxies(): return getproxies_environment() or getproxies_macosx_sysconf() elif os.name == 'nt': def getproxies_registry(): """Return a dictionary of scheme -> proxy server URL mappings. Win32 uses the registry to store proxies. """ proxies = {} try: import _winreg except ImportError: # Std module, so should be around - but you never know! return proxies try: internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') proxyEnable = _winreg.QueryValueEx(internetSettings, 'ProxyEnable')[0] if proxyEnable: # Returned as Unicode but problems if not converted to ASCII proxyServer = str(_winreg.QueryValueEx(internetSettings, 'ProxyServer')[0]) if '=' in proxyServer: # Per-protocol settings for p in proxyServer.split(';'): protocol, address = p.split('=', 1) # See if address has a type:// prefix import re if not re.match('^([^/:]+)://', address): address = '%s://%s' % (protocol, address) proxies[protocol] = address else: # Use one setting for all protocols if proxyServer[:5] == 'http:': proxies['http'] = proxyServer else: proxies['http'] = 'http://%s' % proxyServer proxies['https'] = 'https://%s' % proxyServer proxies['ftp'] = 'ftp://%s' % proxyServer internetSettings.Close() except (WindowsError, ValueError, TypeError): # Either registry key not found etc, or the value in an # unexpected format. # proxies already set up to be empty so nothing to do pass return proxies def getproxies(): """Return a dictionary of scheme -> proxy server URL mappings. Returns settings gathered from the environment, if specified, or the registry. """ return getproxies_environment() or getproxies_registry() def proxy_bypass_registry(host): try: import _winreg import re except ImportError: # Std modules, so should be around - but you never know! return 0 try: internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') proxyEnable = _winreg.QueryValueEx(internetSettings, 'ProxyEnable')[0] proxyOverride = str(_winreg.QueryValueEx(internetSettings, 'ProxyOverride')[0]) # ^^^^ Returned as Unicode but problems if not converted to ASCII except WindowsError: return 0 if not proxyEnable or not proxyOverride: return 0 # try to make a host list from name and IP address. rawHost, port = splitport(host) host = [rawHost] try: addr = socket.gethostbyname(rawHost) if addr != rawHost: host.append(addr) except socket.error: pass try: fqdn = socket.getfqdn(rawHost) if fqdn != rawHost: host.append(fqdn) except socket.error: pass # make a check value list from the registry entry: replace the # '<local>' string by the localhost entry and the corresponding # canonical entry. proxyOverride = proxyOverride.split(';') # now check if we match one of the registry values. for test in proxyOverride: if test == '<local>': if '.' not in rawHost: return 1 test = test.replace(".", r"\.") # mask dots test = test.replace("*", r".*") # change glob sequence test = test.replace("?", r".") # change glob char for val in host: # print "%s <--> %s" %( test, val ) if re.match(test, val, re.I): return 1 return 0 def proxy_bypass(host): """Return True, if the host should be bypassed. Checks proxy settings gathered from the environment, if specified, or the registry. """ proxies = getproxies_environment() if proxies: return proxy_bypass_environment(host, proxies) else: return proxy_bypass_registry(host) else: # By default use environment variables getproxies = getproxies_environment proxy_bypass = proxy_bypass_environment # Test and time quote() and unquote() def test1(): s = '' for i in range(256): s = s + chr(i) s = s*4 t0 = time.time() qs = quote(s) uqs = unquote(qs) t1 = time.time() if uqs != s: print 'Wrong!' print repr(s) print repr(qs) print repr(uqs) print round(t1 - t0, 3), 'sec' def reporthook(blocknum, blocksize, totalsize): # Report during remote transfers print "Block number: %d, Block size: %d, Total size: %d" % ( blocknum, blocksize, totalsize)
Save