/
usr
/
lib
/
python2.6
/
/usr/lib/python2.6
mkdir
upload
Name
Size
Mode
Actions
bsddb/
-
0755
rm
compiler/
-
0755
rm
config/
-
0755
rm
ctypes/
-
0755
rm
curses/
-
0755
rm
distutils/
-
0755
rm
email/
-
0755
rm
encodings/
-
0755
rm
hotshot/
-
0755
rm
idlelib/
-
0755
rm
json/
-
0755
rm
lib-dynload/
-
0755
rm
lib2to3/
-
0755
rm
logging/
-
0755
rm
multiprocessing/
-
0755
rm
plat-linux2/
-
0755
rm
site-packages/
-
0755
rm
sqlite3/
-
0755
rm
test/
-
0755
rm
wsgiref/
-
0755
rm
xml/
-
0755
rm
abc.py
7034
0644
edit
dl
rm
abc.pyc
6049
0644
edit
dl
rm
abc.pyo
5991
0644
edit
dl
rm
aifc.py
33188
0644
edit
dl
rm
aifc.pyc
29424
0644
edit
dl
rm
aifc.pyo
29424
0644
edit
dl
rm
anydbm.py
2620
0644
edit
dl
rm
anydbm.pyc
2769
0644
edit
dl
rm
anydbm.pyo
2769
0644
edit
dl
rm
ast.py
11347
0644
edit
dl
rm
ast.pyc
12732
0644
edit
dl
rm
ast.pyo
12732
0644
edit
dl
rm
asynchat.py
11402
0644
edit
dl
rm
asynchat.pyc
8677
0644
edit
dl
rm
asynchat.pyo
8677
0644
edit
dl
rm
asyncore.py
20061
0644
edit
dl
rm
asyncore.pyc
18334
0644
edit
dl
rm
asyncore.pyo
18334
0644
edit
dl
rm
atexit.py
1705
0644
edit
dl
rm
atexit.pyc
2203
0644
edit
dl
rm
atexit.pyo
2203
0644
edit
dl
rm
audiodev.py
7597
0644
edit
dl
rm
audiodev.pyc
8483
0644
edit
dl
rm
audiodev.pyo
8483
0644
edit
dl
rm
base64.py
11335
0755
edit
dl
rm
base64.pyc
10967
0644
edit
dl
rm
base64.pyo
10967
0644
edit
dl
rm
BaseHTTPServer.py
21974
0644
edit
dl
rm
BaseHTTPServer.pyc
21535
0644
edit
dl
rm
BaseHTTPServer.pyo
21535
0644
edit
dl
rm
Bastion.py
5744
0644
edit
dl
rm
Bastion.pyc
6637
0644
edit
dl
rm
Bastion.pyo
6637
0644
edit
dl
rm
bdb.py
20597
0644
edit
dl
rm
bdb.pyc
18449
0644
edit
dl
rm
bdb.pyo
18449
0644
edit
dl
rm
binhex.py
14878
0644
edit
dl
rm
binhex.pyc
15773
0644
edit
dl
rm
binhex.pyo
15773
0644
edit
dl
rm
bisect.py
2662
0644
edit
dl
rm
bisect.pyc
3163
0644
edit
dl
rm
bisect.pyo
3163
0644
edit
dl
rm
calendar.py
23110
0644
edit
dl
rm
calendar.pyc
28007
0644
edit
dl
rm
calendar.pyo
28007
0644
edit
dl
rm
cgi.py
34478
0755
edit
dl
rm
cgi.pyc
32680
0644
edit
dl
rm
cgi.pyo
32680
0644
edit
dl
rm
CGIHTTPServer.py
12773
0644
edit
dl
rm
CGIHTTPServer.pyc
10794
0644
edit
dl
rm
CGIHTTPServer.pyo
10794
0644
edit
dl
rm
cgitb.py
12155
0644
edit
dl
rm
cgitb.pyc
12425
0644
edit
dl
rm
cgitb.pyo
12425
0644
edit
dl
rm
chunk.py
5372
0644
edit
dl
rm
chunk.pyc
5623
0644
edit
dl
rm
chunk.pyo
5623
0644
edit
dl
rm
cmd.py
14962
0644
edit
dl
rm
cmd.pyc
13914
0644
edit
dl
rm
cmd.pyo
13914
0644
edit
dl
rm
code.py
10217
0644
edit
dl
rm
code.pyc
10395
0644
edit
dl
rm
code.pyo
10395
0644
edit
dl
rm
codecs.py
35266
0644
edit
dl
rm
codecs.pyc
36533
0644
edit
dl
rm
codecs.pyo
36533
0644
edit
dl
rm
codeop.py
5999
0644
edit
dl
rm
codeop.pyc
6616
0644
edit
dl
rm
codeop.pyo
6616
0644
edit
dl
rm
collections.py
13730
0644
edit
dl
rm
collections.pyc
14392
0644
edit
dl
rm
collections.pyo
14339
0644
edit
dl
rm
colorsys.py
3459
0644
edit
dl
rm
colorsys.pyc
4025
0644
edit
dl
rm
colorsys.pyo
4025
0644
edit
dl
rm
commands.py
2543
0644
edit
dl
rm
commands.pyc
2477
0644
edit
dl
rm
commands.pyo
2477
0644
edit
dl
rm
compileall.py
5285
0644
edit
dl
rm
compileall.pyc
4989
0644
edit
dl
rm
compileall.pyo
4989
0644
edit
dl
rm
ConfigParser.py
25989
0644
edit
dl
rm
ConfigParser.pyc
23755
0644
edit
dl
rm
ConfigParser.pyo
23755
0644
edit
dl
rm
contextlib.py
4136
0644
edit
dl
rm
contextlib.pyc
4127
0644
edit
dl
rm
contextlib.pyo
4127
0644
edit
dl
rm
Cookie.py
25054
0644
edit
dl
rm
Cookie.pyc
22067
0644
edit
dl
rm
Cookie.pyo
22067
0644
edit
dl
rm
cookielib.py
64726
0644
edit
dl
rm
cookielib.pyc
55176
0644
edit
dl
rm
cookielib.pyo
54985
0644
edit
dl
rm
copy.py
11177
0644
edit
dl
rm
copy.pyc
11629
0644
edit
dl
rm
copy.pyo
11533
0644
edit
dl
rm
copy_reg.py
6800
0644
edit
dl
rm
copy_reg.pyc
5156
0644
edit
dl
rm
copy_reg.pyo
5110
0644
edit
dl
rm
cProfile.py
6337
0755
edit
dl
rm
cProfile.pyc
6211
0644
edit
dl
rm
cProfile.pyo
6211
0644
edit
dl
rm
crypt.py
2229
0644
edit
dl
rm
crypt.pyc
3043
0644
edit
dl
rm
crypt.pyo
3043
0644
edit
dl
rm
csv.py
15730
0644
edit
dl
rm
csv.pyc
13170
0644
edit
dl
rm
csv.pyo
13170
0644
edit
dl
rm
dbhash.py
535
0644
edit
dl
rm
dbhash.pyc
756
0644
edit
dl
rm
dbhash.pyo
756
0644
edit
dl
rm
decimal.py
199273
0644
edit
dl
rm
decimal.pyc
155185
0644
edit
dl
rm
decimal.pyo
155119
0644
edit
dl
rm
difflib.py
81080
0644
edit
dl
rm
difflib.pyc
61093
0644
edit
dl
rm
difflib.pyo
61039
0644
edit
dl
rm
dircache.py
1126
0644
edit
dl
rm
dircache.pyc
1576
0644
edit
dl
rm
dircache.pyo
1576
0644
edit
dl
rm
dis.py
6449
0644
edit
dl
rm
dis.pyc
6350
0644
edit
dl
rm
dis.pyo
6350
0644
edit
dl
rm
doctest.py
101516
0644
edit
dl
rm
doctest.pyc
80782
0644
edit
dl
rm
doctest.pyo
80494
0644
edit
dl
rm
DocXMLRPCServer.py
10599
0644
edit
dl
rm
DocXMLRPCServer.pyc
9921
0644
edit
dl
rm
DocXMLRPCServer.pyo
9813
0644
edit
dl
rm
dumbdbm.py
8820
0644
edit
dl
rm
dumbdbm.pyc
6547
0644
edit
dl
rm
dumbdbm.pyo
6547
0644
edit
dl
rm
dummy_thread.py
4418
0644
edit
dl
rm
dummy_thread.pyc
5383
0644
edit
dl
rm
dummy_thread.pyo
5383
0644
edit
dl
rm
dummy_threading.py
2804
0644
edit
dl
rm
dummy_threading.pyc
1295
0644
edit
dl
rm
dummy_threading.pyo
1295
0644
edit
dl
rm
filecmp.py
9470
0644
edit
dl
rm
filecmp.pyc
9592
0644
edit
dl
rm
filecmp.pyo
9592
0644
edit
dl
rm
fileinput.py
14143
0644
edit
dl
rm
fileinput.pyc
14870
0644
edit
dl
rm
fileinput.pyo
14870
0644
edit
dl
rm
fnmatch.py
3239
0644
edit
dl
rm
fnmatch.pyc
3567
0644
edit
dl
rm
fnmatch.pyo
3567
0644
edit
dl
rm
formatter.py
14911
0644
edit
dl
rm
formatter.pyc
19149
0644
edit
dl
rm
formatter.pyo
19149
0644
edit
dl
rm
fpformat.py
4699
0644
edit
dl
rm
fpformat.pyc
4719
0644
edit
dl
rm
fpformat.pyo
4719
0644
edit
dl
rm
fractions.py
20073
0644
edit
dl
rm
fractions.pyc
18041
0644
edit
dl
rm
fractions.pyo
18041
0644
edit
dl
rm
ftplib.py
29197
0644
edit
dl
rm
ftplib.pyc
28387
0644
edit
dl
rm
ftplib.pyo
28387
0644
edit
dl
rm
functools.py
2162
0644
edit
dl
rm
functools.pyc
1921
0644
edit
dl
rm
functools.pyo
1921
0644
edit
dl
rm
genericpath.py
3020
0644
edit
dl
rm
genericpath.pyc
3272
0644
edit
dl
rm
genericpath.pyo
3272
0644
edit
dl
rm
getopt.py
7328
0644
edit
dl
rm
getopt.pyc
6710
0644
edit
dl
rm
getopt.pyo
6663
0644
edit
dl
rm
getpass.py
5534
0644
edit
dl
rm
getpass.pyc
4740
0644
edit
dl
rm
getpass.pyo
4740
0644
edit
dl
rm
gettext.py
19968
0644
edit
dl
rm
gettext.pyc
15674
0644
edit
dl
rm
gettext.pyo
15674
0644
edit
dl
rm
glob.py
2249
0644
edit
dl
rm
glob.pyc
2395
0644
edit
dl
rm
glob.pyo
2395
0644
edit
dl
rm
gzip.py
16754
0644
edit
dl
rm
gzip.pyc
14322
0644
edit
dl
rm
gzip.pyo
14322
0644
edit
dl
rm
hashlib.py
4427
0644
edit
dl
rm
hashlib.pyc
3975
0644
edit
dl
rm
hashlib.pyo
3975
0644
edit
dl
rm
heapq.py
15995
0644
edit
dl
rm
heapq.pyc
12668
0644
edit
dl
rm
heapq.pyo
12668
0644
edit
dl
rm
hmac.py
4531
0644
edit
dl
rm
hmac.pyc
4489
0644
edit
dl
rm
hmac.pyo
4489
0644
edit
dl
rm
htmlentitydefs.py
18054
0644
edit
dl
rm
htmlentitydefs.pyc
6369
0644
edit
dl
rm
htmlentitydefs.pyo
6369
0644
edit
dl
rm
htmllib.py
12869
0644
edit
dl
rm
htmllib.pyc
20202
0644
edit
dl
rm
htmllib.pyo
20202
0644
edit
dl
rm
HTMLParser.py
13576
0644
edit
dl
rm
HTMLParser.pyc
12198
0644
edit
dl
rm
HTMLParser.pyo
11890
0644
edit
dl
rm
httplib.py
48797
0644
edit
dl
rm
httplib.pyc
37578
0644
edit
dl
rm
httplib.pyo
37382
0644
edit
dl
rm
ihooks.py
17452
0644
edit
dl
rm
ihooks.pyc
20699
0644
edit
dl
rm
ihooks.pyo
20620
0644
edit
dl
rm
imaplib.py
47771
0644
edit
dl
rm
imaplib.pyc
45027
0644
edit
dl
rm
imaplib.pyo
42287
0644
edit
dl
rm
imghdr.py
3544
0644
edit
dl
rm
imghdr.pyc
4873
0644
edit
dl
rm
imghdr.pyo
4873
0644
edit
dl
rm
imputil.py
26009
0644
edit
dl
rm
imputil.pyc
15959
0644
edit
dl
rm
imputil.pyo
15787
0644
edit
dl
rm
inspect.py
38189
0644
edit
dl
rm
inspect.pyc
37033
0644
edit
dl
rm
inspect.pyo
37033
0644
edit
dl
rm
io.py
66165
0644
edit
dl
rm
io.pyc
62712
0644
edit
dl
rm
io.pyo
62712
0644
edit
dl
rm
keyword.py
1997
0755
edit
dl
rm
keyword.pyc
2113
0644
edit
dl
rm
keyword.pyo
2113
0644
edit
dl
rm
linecache.py
4128
0644
edit
dl
rm
linecache.pyc
3256
0644
edit
dl
rm
linecache.pyo
3256
0644
edit
dl
rm
locale.py
82674
0644
edit
dl
rm
locale.pyc
46620
0644
edit
dl
rm
locale.pyo
46620
0644
edit
dl
rm
macpath.py
6253
0644
edit
dl
rm
macpath.pyc
7669
0644
edit
dl
rm
macpath.pyo
7669
0644
edit
dl
rm
macurl2path.py
3275
0644
edit
dl
rm
macurl2path.pyc
2815
0644
edit
dl
rm
macurl2path.pyo
2815
0644
edit
dl
rm
mailbox.py
75824
0644
edit
dl
rm
mailbox.pyc
75633
0644
edit
dl
rm
mailbox.pyo
75584
0644
edit
dl
rm
mailcap.py
8402
0644
edit
dl
rm
mailcap.pyc
8051
0644
edit
dl
rm
mailcap.pyo
8051
0644
edit
dl
rm
markupbase.py
14350
0644
edit
dl
rm
markupbase.pyc
9430
0644
edit
dl
rm
markupbase.pyo
9236
0644
edit
dl
rm
md5.py
410
0644
edit
dl
rm
md5.pyc
376
0644
edit
dl
rm
md5.pyo
376
0644
edit
dl
rm
mhlib.py
33434
0644
edit
dl
rm
mhlib.pyc
33981
0644
edit
dl
rm
mhlib.pyo
33981
0644
edit
dl
rm
mimetools.py
7168
0644
edit
dl
rm
mimetools.pyc
8280
0644
edit
dl
rm
mimetools.pyo
8280
0644
edit
dl
rm
mimetypes.py
18822
0644
edit
dl
rm
mimetypes.pyc
16838
0644
edit
dl
rm
mimetypes.pyo
16838
0644
edit
dl
rm
MimeWriter.py
6482
0644
edit
dl
rm
MimeWriter.pyc
7365
0644
edit
dl
rm
MimeWriter.pyo
7365
0644
edit
dl
rm
mimify.py
15024
0755
edit
dl
rm
mimify.pyc
12189
0644
edit
dl
rm
mimify.pyo
12189
0644
edit
dl
rm
modulefinder.py
24283
0644
edit
dl
rm
modulefinder.pyc
18939
0644
edit
dl
rm
modulefinder.pyo
18851
0644
edit
dl
rm
multifile.py
4820
0644
edit
dl
rm
multifile.pyc
5449
0644
edit
dl
rm
multifile.pyo
5405
0644
edit
dl
rm
mutex.py
1866
0644
edit
dl
rm
mutex.pyc
2512
0644
edit
dl
rm
mutex.pyo
2512
0644
edit
dl
rm
netrc.py
4111
0644
edit
dl
rm
netrc.pyc
3586
0644
edit
dl
rm
netrc.pyo
3586
0644
edit
dl
rm
new.py
706
0644
edit
dl
rm
new.pyc
908
0644
edit
dl
rm
new.pyo
908
0644
edit
dl
rm
nntplib.py
21470
0644
edit
dl
rm
nntplib.pyc
21091
0644
edit
dl
rm
nntplib.pyo
21091
0644
edit
dl
rm
ntpath.py
17752
0644
edit
dl
rm
ntpath.pyc
11582
0644
edit
dl
rm
ntpath.pyo
11535
0644
edit
dl
rm
nturl2path.py
2239
0644
edit
dl
rm
nturl2path.pyc
1771
0644
edit
dl
rm
nturl2path.pyo
1771
0644
edit
dl
rm
numbers.py
10271
0644
edit
dl
rm
numbers.pyc
13840
0644
edit
dl
rm
numbers.pyo
13840
0644
edit
dl
rm
opcode.py
5248
0644
edit
dl
rm
opcode.pyc
5907
0644
edit
dl
rm
opcode.pyo
5907
0644
edit
dl
rm
optparse.py
60849
0644
edit
dl
rm
optparse.pyc
53959
0644
edit
dl
rm
optparse.pyo
53877
0644
edit
dl
rm
ordereddict.py
36
0644
edit
dl
rm
ordereddict.pyc
183
0644
edit
dl
rm
ordereddict.pyo
183
0644
edit
dl
rm
os.py
25802
0644
edit
dl
rm
os.pyc
25702
0644
edit
dl
rm
os.pyo
25702
0644
edit
dl
rm
os2emxpath.py
4603
0644
edit
dl
rm
os2emxpath.pyc
4518
0644
edit
dl
rm
os2emxpath.pyo
4518
0644
edit
dl
rm
pdb.doc
7899
0644
edit
dl
rm
pdb.py
45333
0755
edit
dl
rm
pdb.pyc
43585
0644
edit
dl
rm
pdb.pyo
43585
0644
edit
dl
rm
pickle.py
44811
0644
edit
dl
rm
pickle.pyc
38437
0644
edit
dl
rm
pickle.pyo
38232
0644
edit
dl
rm
pickletools.py
74348
0644
edit
dl
rm
pickletools.pyc
57079
0644
edit
dl
rm
pickletools.pyo
56182
0644
edit
dl
rm
pipes.py
9647
0644
edit
dl
rm
pipes.pyc
9428
0644
edit
dl
rm
pipes.pyo
9428
0644
edit
dl
rm
pkgutil.py
20001
0644
edit
dl
rm
pkgutil.pyc
18954
0644
edit
dl
rm
pkgutil.pyo
18954
0644
edit
dl
rm
platform.py
52630
0755
edit
dl
rm
platform.pyc
38699
0644
edit
dl
rm
platform.pyo
38699
0644
edit
dl
rm
plistlib.py
15806
0644
edit
dl
rm
plistlib.pyc
19926
0644
edit
dl
rm
plistlib.pyo
19836
0644
edit
dl
rm
popen2.py
8416
0644
edit
dl
rm
popen2.pyc
9032
0644
edit
dl
rm
popen2.pyo
8988
0644
edit
dl
rm
poplib.py
12825
0644
edit
dl
rm
poplib.pyc
13352
0644
edit
dl
rm
poplib.pyo
13352
0644
edit
dl
rm
posixfile.py
8003
0644
edit
dl
rm
posixfile.pyc
7700
0644
edit
dl
rm
posixfile.pyo
7700
0644
edit
dl
rm
posixpath.py
13119
0644
edit
dl
rm
posixpath.pyc
11142
0644
edit
dl
rm
posixpath.pyo
11142
0644
edit
dl
rm
pprint.py
11932
0644
edit
dl
rm
pprint.pyc
10356
0644
edit
dl
rm
pprint.pyo
10181
0644
edit
dl
rm
profile.py
23510
0755
edit
dl
rm
profile.pyc
16600
0644
edit
dl
rm
profile.pyo
16355
0644
edit
dl
rm
pstats.py
27310
0644
edit
dl
rm
pstats.pyc
25212
0644
edit
dl
rm
pstats.pyo
25212
0644
edit
dl
rm
pty.py
4869
0644
edit
dl
rm
pty.pyc
4899
0644
edit
dl
rm
pty.pyo
4899
0644
edit
dl
rm
pyclbr.py
13282
0644
edit
dl
rm
pyclbr.pyc
9706
0644
edit
dl
rm
pyclbr.pyo
9706
0644
edit
dl
rm
pydoc.py
92432
0755
edit
dl
rm
pydoc.pyc
90662
0644
edit
dl
rm
pydoc.pyo
90594
0644
edit
dl
rm
pydoc_topics.py
423126
0644
edit
dl
rm
pydoc_topics.pyc
407586
0644
edit
dl
rm
pydoc_topics.pyo
407586
0644
edit
dl
rm
py_compile.py
5633
0644
edit
dl
rm
py_compile.pyc
6536
0644
edit
dl
rm
py_compile.pyo
6536
0644
edit
dl
rm
Queue.py
8574
0644
edit
dl
rm
Queue.pyc
9391
0644
edit
dl
rm
Queue.pyo
9391
0644
edit
dl
rm
quopri.py
6972
0755
edit
dl
rm
quopri.pyc
6666
0644
edit
dl
rm
quopri.pyo
6666
0644
edit
dl
rm
random.py
31966
0644
edit
dl
rm
random.pyc
25024
0644
edit
dl
rm
random.pyo
25024
0644
edit
dl
rm
re.py
12966
0644
edit
dl
rm
re.pyc
13122
0644
edit
dl
rm
re.pyo
13122
0644
edit
dl
rm
repr.py
4296
0644
edit
dl
rm
repr.pyc
5400
0644
edit
dl
rm
repr.pyo
5400
0644
edit
dl
rm
rexec.py
20152
0644
edit
dl
rm
rexec.pyc
24102
0644
edit
dl
rm
rexec.pyo
24102
0644
edit
dl
rm
rfc822.py
33295
0644
edit
dl
rm
rfc822.pyc
31990
0644
edit
dl
rm
rfc822.pyo
31990
0644
edit
dl
rm
rlcompleter.py
5866
0644
edit
dl
rm
rlcompleter.pyc
6057
0644
edit
dl
rm
rlcompleter.pyo
6057
0644
edit
dl
rm
robotparser.py
7014
0644
edit
dl
rm
robotparser.pyc
7804
0644
edit
dl
rm
robotparser.pyo
7804
0644
edit
dl
rm
runpy.py
5413
0644
edit
dl
rm
runpy.pyc
3965
0644
edit
dl
rm
runpy.pyo
3965
0644
edit
dl
rm
sched.py
5091
0644
edit
dl
rm
sched.pyc
4987
0644
edit
dl
rm
sched.pyo
4987
0644
edit
dl
rm
sets.py
19050
0644
edit
dl
rm
sets.pyc
16885
0644
edit
dl
rm
sets.pyo
16885
0644
edit
dl
rm
sgmllib.py
17884
0644
edit
dl
rm
sgmllib.pyc
15504
0644
edit
dl
rm
sgmllib.pyo
15504
0644
edit
dl
rm
sha.py
445
0644
edit
dl
rm
sha.pyc
419
0644
edit
dl
rm
sha.pyo
419
0644
edit
dl
rm
shelve.py
8078
0644
edit
dl
rm
shelve.pyc
10242
0644
edit
dl
rm
shelve.pyo
10242
0644
edit
dl
rm
shlex.py
11137
0644
edit
dl
rm
shlex.pyc
7684
0644
edit
dl
rm
shlex.pyo
7684
0644
edit
dl
rm
shutil.py
8632
0644
edit
dl
rm
shutil.pyc
9519
0644
edit
dl
rm
shutil.pyo
9519
0644
edit
dl
rm
SimpleHTTPServer.py
7422
0644
edit
dl
rm
SimpleHTTPServer.pyc
7744
0644
edit
dl
rm
SimpleHTTPServer.pyo
7744
0644
edit
dl
rm
SimpleXMLRPCServer.py
21992
0644
edit
dl
rm
SimpleXMLRPCServer.pyc
19575
0644
edit
dl
rm
SimpleXMLRPCServer.pyo
19575
0644
edit
dl
rm
site.py
18927
0644
edit
dl
rm
site.pyc
18663
0644
edit
dl
rm
site.pyo
18663
0644
edit
dl
rm
smtpd.py
18920
0755
edit
dl
rm
smtpd.pyc
16126
0644
edit
dl
rm
smtpd.pyo
16126
0644
edit
dl
rm
smtplib.py
30924
0755
edit
dl
rm
smtplib.pyc
29629
0644
edit
dl
rm
smtplib.pyo
29629
0644
edit
dl
rm
sndhdr.py
5973
0644
edit
dl
rm
sndhdr.pyc
7386
0644
edit
dl
rm
sndhdr.pyo
7386
0644
edit
dl
rm
socket.py
20149
0644
edit
dl
rm
socket.pyc
16067
0644
edit
dl
rm
socket.pyo
15982
0644
edit
dl
rm
SocketServer.py
22326
0644
edit
dl
rm
SocketServer.pyc
23035
0644
edit
dl
rm
SocketServer.pyo
23035
0644
edit
dl
rm
sre.py
384
0644
edit
dl
rm
sre.pyc
517
0644
edit
dl
rm
sre.pyo
517
0644
edit
dl
rm
sre_compile.py
16507
0644
edit
dl
rm
sre_compile.pyc
11455
0644
edit
dl
rm
sre_compile.pyo
11342
0644
edit
dl
rm
sre_constants.py
7137
0644
edit
dl
rm
sre_constants.pyc
6083
0644
edit
dl
rm
sre_constants.pyo
6083
0644
edit
dl
rm
sre_parse.py
26878
0644
edit
dl
rm
sre_parse.pyc
19622
0644
edit
dl
rm
sre_parse.pyo
19622
0644
edit
dl
rm
ssl.py
16677
0644
edit
dl
rm
ssl.pyc
14218
0644
edit
dl
rm
ssl.pyo
14218
0644
edit
dl
rm
stat.py
1718
0644
edit
dl
rm
stat.pyc
2683
0644
edit
dl
rm
stat.pyo
2683
0644
edit
dl
rm
statvfs.py
898
0644
edit
dl
rm
statvfs.pyc
618
0644
edit
dl
rm
statvfs.pyo
618
0644
edit
dl
rm
string.py
20745
0644
edit
dl
rm
string.pyc
19964
0644
edit
dl
rm
string.pyo
19964
0644
edit
dl
rm
StringIO.py
10621
0644
edit
dl
rm
StringIO.pyc
11494
0644
edit
dl
rm
StringIO.pyo
11494
0644
edit
dl
rm
stringold.py
12449
0644
edit
dl
rm
stringold.pyc
12539
0644
edit
dl
rm
stringold.pyo
12539
0644
edit
dl
rm
stringprep.py
13522
0644
edit
dl
rm
stringprep.pyc
14486
0644
edit
dl
rm
stringprep.pyo
14412
0644
edit
dl
rm
struct.py
82
0644
edit
dl
rm
struct.pyc
237
0644
edit
dl
rm
struct.pyo
237
0644
edit
dl
rm
subprocess.py
57945
0644
edit
dl
rm
subprocess.pyc
40975
0644
edit
dl
rm
subprocess.pyo
40918
0644
edit
dl
rm
sunau.py
16537
0644
edit
dl
rm
sunau.pyc
17976
0644
edit
dl
rm
sunau.pyo
17976
0644
edit
dl
rm
sunaudio.py
1399
0644
edit
dl
rm
sunaudio.pyc
1987
0644
edit
dl
rm
sunaudio.pyo
1987
0644
edit
dl
rm
symbol.py
2050
0755
edit
dl
rm
symbol.pyc
3021
0644
edit
dl
rm
symbol.pyo
3021
0644
edit
dl
rm
symtable.py
7911
0644
edit
dl
rm
symtable.pyc
12503
0644
edit
dl
rm
symtable.pyo
12373
0644
edit
dl
rm
tabnanny.py
11339
0755
edit
dl
rm
tabnanny.pyc
8293
0644
edit
dl
rm
tabnanny.pyo
8293
0644
edit
dl
rm
tarfile.py
87786
0644
edit
dl
rm
tarfile.pyc
73596
0644
edit
dl
rm
tarfile.pyo
73596
0644
edit
dl
rm
telnetlib.py
21808
0644
edit
dl
rm
telnetlib.pyc
19855
0644
edit
dl
rm
telnetlib.pyo
19855
0644
edit
dl
rm
tempfile.py
17774
0644
edit
dl
rm
tempfile.pyc
19463
0644
edit
dl
rm
tempfile.pyo
19463
0644
edit
dl
rm
textwrap.py
16889
0644
edit
dl
rm
textwrap.pyc
11766
0644
edit
dl
rm
textwrap.pyo
11674
0644
edit
dl
rm
this.py
1002
0644
edit
dl
rm
this.pyc
1239
0644
edit
dl
rm
this.pyo
1239
0644
edit
dl
rm
threading.py
31808
0644
edit
dl
rm
threading.pyc
27956
0644
edit
dl
rm
threading.pyo
25884
0644
edit
dl
rm
timeit.py
12003
0644
edit
dl
rm
timeit.pyc
11801
0644
edit
dl
rm
timeit.pyo
11801
0644
edit
dl
rm
toaiff.py
3142
0644
edit
dl
rm
toaiff.pyc
3126
0644
edit
dl
rm
toaiff.pyo
3126
0644
edit
dl
rm
token.py
2947
0755
edit
dl
rm
token.pyc
3830
0644
edit
dl
rm
token.pyo
3830
0644
edit
dl
rm
tokenize.py
16326
0644
edit
dl
rm
tokenize.pyc
13986
0644
edit
dl
rm
tokenize.pyo
13893
0644
edit
dl
rm
trace.py
30325
0644
edit
dl
rm
trace.pyc
22989
0644
edit
dl
rm
trace.pyo
22927
0644
edit
dl
rm
traceback.py
11211
0644
edit
dl
rm
traceback.pyc
11637
0644
edit
dl
rm
traceback.pyo
11637
0644
edit
dl
rm
tty.py
879
0644
edit
dl
rm
tty.pyc
1311
0644
edit
dl
rm
tty.pyo
1311
0644
edit
dl
rm
types.py
2323
0644
edit
dl
rm
types.pyc
2608
0644
edit
dl
rm
types.pyo
2608
0644
edit
dl
rm
unittest.py
31157
0644
edit
dl
rm
unittest.pyc
34656
0644
edit
dl
rm
unittest.pyo
34656
0644
edit
dl
rm
urllib.py
59022
0644
edit
dl
rm
urllib.pyc
51142
0644
edit
dl
rm
urllib.pyo
51048
0644
edit
dl
rm
urllib2.py
50866
0644
edit
dl
rm
urllib2.pyc
45569
0644
edit
dl
rm
urllib2.pyo
45475
0644
edit
dl
rm
urlparse.py
15618
0644
edit
dl
rm
urlparse.pyc
14727
0644
edit
dl
rm
urlparse.pyo
14727
0644
edit
dl
rm
user.py
1627
0644
edit
dl
rm
user.pyc
1734
0644
edit
dl
rm
user.pyo
1734
0644
edit
dl
rm
UserDict.py
5778
0644
edit
dl
rm
UserDict.pyc
8802
0644
edit
dl
rm
UserDict.pyo
8802
0644
edit
dl
rm
UserList.py
3644
0644
edit
dl
rm
UserList.pyc
6535
0644
edit
dl
rm
UserList.pyo
6535
0644
edit
dl
rm
UserString.py
9691
0755
edit
dl
rm
UserString.pyc
14786
0644
edit
dl
rm
UserString.pyo
14786
0644
edit
dl
rm
uu.py
5942
0755
edit
dl
rm
uu.pyc
4227
0644
edit
dl
rm
uu.pyo
4227
0644
edit
dl
rm
uuid.py
20944
0644
edit
dl
rm
uuid.pyc
21205
0644
edit
dl
rm
uuid.pyo
21205
0644
edit
dl
rm
warnings.py
14172
0644
edit
dl
rm
warnings.pyc
12996
0644
edit
dl
rm
warnings.pyo
12159
0644
edit
dl
rm
wave.py
17952
0644
edit
dl
rm
wave.pyc
19336
0644
edit
dl
rm
wave.pyo
19336
0644
edit
dl
rm
weakref.py
10087
0644
edit
dl
rm
weakref.pyc
13277
0644
edit
dl
rm
weakref.pyo
13277
0644
edit
dl
rm
webbrowser.py
21073
0644
edit
dl
rm
webbrowser.pyc
18669
0644
edit
dl
rm
webbrowser.pyo
18622
0644
edit
dl
rm
whichdb.py
3353
0644
edit
dl
rm
whichdb.pyc
2243
0644
edit
dl
rm
whichdb.pyo
2243
0644
edit
dl
rm
xdrlib.py
5513
0644
edit
dl
rm
xdrlib.pyc
9079
0644
edit
dl
rm
xdrlib.pyo
9079
0644
edit
dl
rm
xmllib.py
34865
0644
edit
dl
rm
xmllib.pyc
27166
0644
edit
dl
rm
xmllib.pyo
27166
0644
edit
dl
rm
xmlrpclib.py
47775
0644
edit
dl
rm
xmlrpclib.pyc
41230
0644
edit
dl
rm
xmlrpclib.pyo
41047
0644
edit
dl
rm
zipfile.py
53092
0644
edit
dl
rm
zipfile.pyc
37547
0644
edit
dl
rm
zipfile.pyo
37547
0644
edit
dl
rm
_abcoll.py
14242
0644
edit
dl
rm
_abcoll.pyc
21395
0644
edit
dl
rm
_abcoll.pyo
21395
0644
edit
dl
rm
_LWPCookieJar.py
6553
0644
edit
dl
rm
_LWPCookieJar.pyc
5589
0644
edit
dl
rm
_LWPCookieJar.pyo
5589
0644
edit
dl
rm
_MozillaCookieJar.py
5809
0644
edit
dl
rm
_MozillaCookieJar.pyc
4509
0644
edit
dl
rm
_MozillaCookieJar.pyo
4468
0644
edit
dl
rm
_strptime.py
19754
0644
edit
dl
rm
_strptime.pyc
14926
0644
edit
dl
rm
_strptime.pyo
14926
0644
edit
dl
rm
_threading_local.py
7114
0644
edit
dl
rm
_threading_local.pyc
6367
0644
edit
dl
rm
_threading_local.pyo
6367
0644
edit
dl
rm
__future__.py
4380
0644
edit
dl
rm
__future__.pyc
4221
0644
edit
dl
rm
__future__.pyo
4221
0644
edit
dl
rm
__phello__.foo.py
64
0644
edit
dl
rm
__phello__.foo.pyc
123
0644
edit
dl
rm
__phello__.foo.pyo
123
0644
edit
dl
rm
Edit:
/usr/lib/python2.6/urllib2.py
(50866B)
"""An extensible library for opening URLs using a variety of protocols The simplest way to use this module is to call the urlopen function, which accepts a string containing a URL or a Request object (described below). It opens the URL and returns the results as file-like object; the returned object has some extra methods described below. The OpenerDirector manages a collection of Handler objects that do all the actual work. Each Handler implements a particular protocol or option. The OpenerDirector is a composite object that invokes the Handlers needed to open the requested URL. For example, the HTTPHandler performs HTTP GET and POST requests and deals with non-error returns. The HTTPRedirectHandler automatically deals with HTTP 301, 302, 303 and 307 redirect errors, and the HTTPDigestAuthHandler deals with digest authentication. urlopen(url, data=None) -- Basic usage is the same as original urllib. pass the url and optionally data to post to an HTTP URL, and get a file-like object back. One difference is that you can also pass a Request instance instead of URL. Raises a URLError (subclass of IOError); for HTTP errors, raises an HTTPError, which can also be treated as a valid response. build_opener -- Function that creates a new OpenerDirector instance. Will install the default handlers. Accepts one or more Handlers as arguments, either instances or Handler classes that it will instantiate. If one of the argument is a subclass of the default handler, the argument will be installed instead of the default. install_opener -- Installs a new opener as the default opener. objects of interest: OpenerDirector -- Sets up the User Agent as the Python-urllib client and manages the Handler classes, while dealing with requests and responses. Request -- An object that encapsulates the state of a request. The state can be as simple as the URL. It can also include extra HTTP headers, e.g. a User-Agent. BaseHandler -- exceptions: URLError -- A subclass of IOError, individual protocols have their own specific subclass. HTTPError -- Also a valid HTTP response, so you can treat an HTTP error as an exceptional event or valid response. internals: BaseHandler and parent _call_chain conventions Example usage: import urllib2 # set up authentication info authinfo = urllib2.HTTPBasicAuthHandler() authinfo.add_password(realm='PDQ Application', uri='https://mahler:8092/site-updates.py', user='klem', passwd='geheim$parole') proxy_support = urllib2.ProxyHandler({"http" : "http://ahad-haam:3128"}) # build a new opener that adds authentication and caching FTP handlers opener = urllib2.build_opener(proxy_support, authinfo, urllib2.CacheFTPHandler) # install it urllib2.install_opener(opener) f = urllib2.urlopen('http://www.python.org/') """ # XXX issues: # If an authentication error handler that tries to perform # authentication for some reason but fails, how should the error be # signalled? The client needs to know the HTTP error code. But if # the handler knows that the problem was, e.g., that it didn't know # that hash algo that requested in the challenge, it would be good to # pass that information along to the client, too. # ftp errors aren't handled cleanly # check digest against correct (i.e. non-apache) implementation # Possible extensions: # complex proxies XXX not sure what exactly was meant by this # abstract factory for opener import base64 import hashlib import httplib import mimetools import os import posixpath import random import re import socket import sys import time import urlparse import bisect try: from cStringIO import StringIO except ImportError: from StringIO import StringIO from urllib import (unwrap, unquote, splittype, splithost, quote, addinfourl, splitport, splitattr, ftpwrapper, splituser, splitpasswd, splitvalue) # support for FileHandler, proxies via environment variables from urllib import localhost, url2pathname, getproxies, proxy_bypass # used in User-Agent header sent __version__ = sys.version[:3] _opener = None def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): global _opener if _opener is None: _opener = build_opener() return _opener.open(url, data, timeout) def install_opener(opener): global _opener _opener = opener # do these error classes make sense? # make sure all of the IOError stuff is overridden. we just want to be # subtypes. class URLError(IOError): # URLError is a sub-type of IOError, but it doesn't share any of # the implementation. need to override __init__ and __str__. # It sets self.args for compatibility with other EnvironmentError # subclasses, but args doesn't have the typical format with errno in # slot 0 and strerror in slot 1. This may be better than nothing. def __init__(self, reason): self.args = reason, self.reason = reason def __str__(self): return '<urlopen error %s>' % self.reason class HTTPError(URLError, addinfourl): """Raised when HTTP error occurs, but also acts like non-error return""" __super_init = addinfourl.__init__ def __init__(self, url, code, msg, hdrs, fp): self.code = code self.msg = msg self.hdrs = hdrs self.fp = fp self.filename = url # The addinfourl classes depend on fp being a valid file # object. In some cases, the HTTPError may not have a valid # file object. If this happens, the simplest workaround is to # not initialize the base classes. if fp is not None: self.__super_init(fp, hdrs, url, code) def __str__(self): return 'HTTP Error %s: %s' % (self.code, self.msg) # copied from cookielib.py _cut_port_re = re.compile(r":\d+$") def request_host(request): """Return request-host, as defined by RFC 2965. Variation from RFC: returned value is lowercased, for convenient comparison. """ url = request.get_full_url() host = urlparse.urlparse(url)[1] if host == "": host = request.get_header("Host", "") # remove port, if present host = _cut_port_re.sub("", host, 1) return host.lower() class Request: def __init__(self, url, data=None, headers={}, origin_req_host=None, unverifiable=False): # unwrap('<URL:type://host/path>') --> 'type://host/path' self.__original = unwrap(url) self.type = None # self.__r_type is what's left after doing the splittype self.host = None self.port = None self._tunnel_host = None self.data = data self.headers = {} for key, value in headers.items(): self.add_header(key, value) self.unredirected_hdrs = {} if origin_req_host is None: origin_req_host = request_host(self) self.origin_req_host = origin_req_host self.unverifiable = unverifiable def __getattr__(self, attr): # XXX this is a fallback mechanism to guard against these # methods getting called in a non-standard order. this may be # too complicated and/or unnecessary. # XXX should the __r_XXX attributes be public? if attr[:12] == '_Request__r_': name = attr[12:] if hasattr(Request, 'get_' + name): getattr(self, 'get_' + name)() return getattr(self, attr) raise AttributeError, attr def get_method(self): if self.has_data(): return "POST" else: return "GET" # XXX these helper methods are lame def add_data(self, data): self.data = data def has_data(self): return self.data is not None def get_data(self): return self.data def get_full_url(self): return self.__original def get_type(self): if self.type is None: self.type, self.__r_type = splittype(self.__original) if self.type is None: raise ValueError, "unknown url type: %s" % self.__original return self.type def get_host(self): if self.host is None: self.host, self.__r_host = splithost(self.__r_type) if self.host: self.host = unquote(self.host) return self.host def get_selector(self): return self.__r_host def set_proxy(self, host, type): if self.type == 'https' and not self._tunnel_host: self._tunnel_host = self.host else: self.type = type self.__r_host = self.__original self.host = host def has_proxy(self): return self.__r_host == self.__original def get_origin_req_host(self): return self.origin_req_host def is_unverifiable(self): return self.unverifiable def add_header(self, key, val): # useful for something like authentication self.headers[key.capitalize()] = val def add_unredirected_header(self, key, val): # will not be added to a redirected request self.unredirected_hdrs[key.capitalize()] = val def has_header(self, header_name): return (header_name in self.headers or header_name in self.unredirected_hdrs) def get_header(self, header_name, default=None): return self.headers.get( header_name, self.unredirected_hdrs.get(header_name, default)) def header_items(self): hdrs = self.unredirected_hdrs.copy() hdrs.update(self.headers) return hdrs.items() class OpenerDirector: def __init__(self): client_version = "Python-urllib/%s" % __version__ self.addheaders = [('User-agent', client_version)] # manage the individual handlers self.handlers = [] self.handle_open = {} self.handle_error = {} self.process_response = {} self.process_request = {} def add_handler(self, handler): if not hasattr(handler, "add_parent"): raise TypeError("expected BaseHandler instance, got %r" % type(handler)) added = False for meth in dir(handler): if meth in ["redirect_request", "do_open", "proxy_open"]: # oops, coincidental match continue i = meth.find("_") protocol = meth[:i] condition = meth[i+1:] if condition.startswith("error"): j = condition.find("_") + i + 1 kind = meth[j+1:] try: kind = int(kind) except ValueError: pass lookup = self.handle_error.get(protocol, {}) self.handle_error[protocol] = lookup elif condition == "open": kind = protocol lookup = self.handle_open elif condition == "response": kind = protocol lookup = self.process_response elif condition == "request": kind = protocol lookup = self.process_request else: continue handlers = lookup.setdefault(kind, []) if handlers: bisect.insort(handlers, handler) else: handlers.append(handler) added = True if added: # the handlers must work in an specific order, the order # is specified in a Handler attribute bisect.insort(self.handlers, handler) handler.add_parent(self) def close(self): # Only exists for backwards compatibility. pass def _call_chain(self, chain, kind, meth_name, *args): # Handlers raise an exception if no one else should try to handle # the request, or return None if they can't but another handler # could. Otherwise, they return the response. handlers = chain.get(kind, ()) for handler in handlers: func = getattr(handler, meth_name) result = func(*args) if result is not None: return result def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): # accept a URL or a Request object if isinstance(fullurl, basestring): req = Request(fullurl, data) else: req = fullurl if data is not None: req.add_data(data) req.timeout = timeout protocol = req.get_type() # pre-process request meth_name = protocol+"_request" for processor in self.process_request.get(protocol, []): meth = getattr(processor, meth_name) req = meth(req) response = self._open(req, data) # post-process response meth_name = protocol+"_response" for processor in self.process_response.get(protocol, []): meth = getattr(processor, meth_name) response = meth(req, response) return response def _open(self, req, data=None): result = self._call_chain(self.handle_open, 'default', 'default_open', req) if result: return result protocol = req.get_type() result = self._call_chain(self.handle_open, protocol, protocol + '_open', req) if result: return result return self._call_chain(self.handle_open, 'unknown', 'unknown_open', req) def error(self, proto, *args): if proto in ('http', 'https'): # XXX http[s] protocols are special-cased dict = self.handle_error['http'] # https is not different than http proto = args[2] # YUCK! meth_name = 'http_error_%s' % proto http_err = 1 orig_args = args else: dict = self.handle_error meth_name = proto + '_error' http_err = 0 args = (dict, proto, meth_name) + args result = self._call_chain(*args) if result: return result if http_err: args = (dict, 'default', 'http_error_default') + orig_args return self._call_chain(*args) # XXX probably also want an abstract factory that knows when it makes # sense to skip a superclass in favor of a subclass and when it might # make sense to include both def build_opener(*handlers): """Create an opener object from a list of handlers. The opener will use several default handlers, including support for HTTP, FTP and when applicable, HTTPS. If any of the handlers passed as arguments are subclasses of the default handlers, the default handlers will not be used. """ import types def isclass(obj): return isinstance(obj, types.ClassType) or hasattr(obj, "__bases__") opener = OpenerDirector() default_classes = [ProxyHandler, UnknownHandler, HTTPHandler, HTTPDefaultErrorHandler, HTTPRedirectHandler, FTPHandler, FileHandler, HTTPErrorProcessor] if hasattr(httplib, 'HTTPS'): default_classes.append(HTTPSHandler) skip = set() for klass in default_classes: for check in handlers: if isclass(check): if issubclass(check, klass): skip.add(klass) elif isinstance(check, klass): skip.add(klass) for klass in skip: default_classes.remove(klass) for klass in default_classes: opener.add_handler(klass()) for h in handlers: if isclass(h): h = h() opener.add_handler(h) return opener class BaseHandler: handler_order = 500 def add_parent(self, parent): self.parent = parent def close(self): # Only exists for backwards compatibility pass def __lt__(self, other): if not hasattr(other, "handler_order"): # Try to preserve the old behavior of having custom classes # inserted after default ones (works only for custom user # classes which are not aware of handler_order). return True return self.handler_order < other.handler_order class HTTPErrorProcessor(BaseHandler): """Process HTTP error responses.""" handler_order = 1000 # after all other processing def http_response(self, request, response): code, msg, hdrs = response.code, response.msg, response.info() # According to RFC 2616, "2xx" code indicates that the client's # request was successfully received, understood, and accepted. if not (200 <= code < 300): response = self.parent.error( 'http', request, response, code, msg, hdrs) return response https_response = http_response class HTTPDefaultErrorHandler(BaseHandler): def http_error_default(self, req, fp, code, msg, hdrs): raise HTTPError(req.get_full_url(), code, msg, hdrs, fp) class HTTPRedirectHandler(BaseHandler): # maximum number of redirections to any single URL # this is needed because of the state that cookies introduce max_repeats = 4 # maximum total number of redirections (regardless of URL) before # assuming we're in a loop max_redirections = 10 def redirect_request(self, req, fp, code, msg, headers, newurl): """Return a Request or None in response to a redirect. This is called by the http_error_30x methods when a redirection response is received. If a redirection should take place, return a new Request to allow http_error_30x to perform the redirect. Otherwise, raise HTTPError if no-one else should try to handle this url. Return None if you can't but another Handler might. """ m = req.get_method() if (code in (301, 302, 303, 307) and m in ("GET", "HEAD") or code in (301, 302, 303) and m == "POST"): # Strictly (according to RFC 2616), 301 or 302 in response # to a POST MUST NOT cause a redirection without confirmation # from the user (of urllib2, in this case). In practice, # essentially all clients do redirect in this case, so we # do the same. # be conciliant with URIs containing a space newurl = newurl.replace(' ', '%20') newheaders = dict((k,v) for k,v in req.headers.items() if k.lower() not in ("content-length", "content-type") ) return Request(newurl, headers=newheaders, origin_req_host=req.get_origin_req_host(), unverifiable=True) else: raise HTTPError(req.get_full_url(), code, msg, headers, fp) # Implementation note: To avoid the server sending us into an # infinite loop, the request object needs to track what URLs we # have already seen. Do this by adding a handler-specific # attribute to the Request object. def http_error_302(self, req, fp, code, msg, headers): # Some servers (incorrectly) return multiple Location headers # (so probably same goes for URI). Use first header. if 'location' in headers: newurl = headers.getheaders('location')[0] elif 'uri' in headers: newurl = headers.getheaders('uri')[0] else: return # fix a possible malformed URL urlparts = urlparse.urlparse(newurl) if not urlparts.path: urlparts = list(urlparts) urlparts[2] = "/" newurl = urlparse.urlunparse(urlparts) newurl = urlparse.urljoin(req.get_full_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 HTTPError(newurl, code, msg + " - Redirection to url '%s' is not allowed" % newurl, headers, fp) # XXX Probably want to forget about the state of the current # request, although that might interact poorly with other # handlers that also use handler-specific request attributes new = self.redirect_request(req, fp, code, msg, headers, newurl) if new is None: return # loop detection # .redirect_dict has a key url if url was previously visited. if hasattr(req, 'redirect_dict'): visited = new.redirect_dict = req.redirect_dict if (visited.get(newurl, 0) >= self.max_repeats or len(visited) >= self.max_redirections): raise HTTPError(req.get_full_url(), code, self.inf_msg + msg, headers, fp) else: visited = new.redirect_dict = req.redirect_dict = {} visited[newurl] = visited.get(newurl, 0) + 1 # Don't close the fp until we are sure that we won't use it # with HTTPError. fp.read() fp.close() return self.parent.open(new, timeout=req.timeout) http_error_301 = http_error_303 = http_error_307 = http_error_302 inf_msg = "The HTTP server returned a redirect error that would " \ "lead to an infinite loop.\n" \ "The last 30x error message was:\n" def _parse_proxy(proxy): """Return (scheme, user, password, host/port) given a URL or an authority. If a URL is supplied, it must have an authority (host:port) component. According to RFC 3986, having an authority component means the URL must have two slashes after the scheme: >>> _parse_proxy('file:/ftp.example.com/') Traceback (most recent call last): ValueError: proxy URL with no authority: 'file:/ftp.example.com/' The first three items of the returned tuple may be None. Examples of authority parsing: >>> _parse_proxy('proxy.example.com') (None, None, None, 'proxy.example.com') >>> _parse_proxy('proxy.example.com:3128') (None, None, None, 'proxy.example.com:3128') The authority component may optionally include userinfo (assumed to be username:password): >>> _parse_proxy('joe:password@proxy.example.com') (None, 'joe', 'password', 'proxy.example.com') >>> _parse_proxy('joe:password@proxy.example.com:3128') (None, 'joe', 'password', 'proxy.example.com:3128') Same examples, but with URLs instead: >>> _parse_proxy('http://proxy.example.com/') ('http', None, None, 'proxy.example.com') >>> _parse_proxy('http://proxy.example.com:3128/') ('http', None, None, 'proxy.example.com:3128') >>> _parse_proxy('http://joe:password@proxy.example.com/') ('http', 'joe', 'password', 'proxy.example.com') >>> _parse_proxy('http://joe:password@proxy.example.com:3128') ('http', 'joe', 'password', 'proxy.example.com:3128') Everything after the authority is ignored: >>> _parse_proxy('ftp://joe:password@proxy.example.com/rubbish:3128') ('ftp', 'joe', 'password', 'proxy.example.com') Test for no trailing '/' case: >>> _parse_proxy('http://joe:password@proxy.example.com') ('http', 'joe', 'password', 'proxy.example.com') """ scheme, r_scheme = splittype(proxy) if not r_scheme.startswith("/"): # authority scheme = None authority = proxy else: # URL if not r_scheme.startswith("//"): raise ValueError("proxy URL with no authority: %r" % proxy) # We have an authority, so for RFC 3986-compliant URLs (by ss 3. # and 3.3.), path is empty or starts with '/' end = r_scheme.find("/", 2) if end == -1: end = None authority = r_scheme[2:end] userinfo, hostport = splituser(authority) if userinfo is not None: user, password = splitpasswd(userinfo) else: user = password = None return scheme, user, password, hostport class ProxyHandler(BaseHandler): # Proxies must be in front handler_order = 100 def __init__(self, proxies=None): if proxies is None: proxies = getproxies() assert hasattr(proxies, 'has_key'), "proxies must be a mapping" self.proxies = proxies for type, url in proxies.items(): setattr(self, '%s_open' % type, lambda r, proxy=url, type=type, meth=self.proxy_open: \ meth(r, proxy, type)) def proxy_open(self, req, proxy, type): orig_type = req.get_type() proxy_type, user, password, hostport = _parse_proxy(proxy) if proxy_type is None: proxy_type = orig_type req.get_host() if req.host and proxy_bypass(req.host): return None if user and password: user_pass = '%s:%s' % (unquote(user), unquote(password)) creds = base64.b64encode(user_pass).strip() req.add_header('Proxy-authorization', 'Basic ' + creds) hostport = unquote(hostport) req.set_proxy(hostport, proxy_type) if orig_type == proxy_type or orig_type == 'https': # let other handlers take care of it return None else: # need to start over, because the other handlers don't # grok the proxy's URL type # e.g. if we have a constructor arg proxies like so: # {'http': 'ftp://proxy.example.com'}, we may end up turning # a request for http://acme.example.com/a into one for # ftp://proxy.example.com/a return self.parent.open(req, timeout=req.timeout) class HTTPPasswordMgr: def __init__(self): self.passwd = {} def add_password(self, realm, uri, user, passwd): # uri could be a single URI or a sequence if isinstance(uri, basestring): uri = [uri] if not realm in self.passwd: self.passwd[realm] = {} for default_port in True, False: reduced_uri = tuple( [self.reduce_uri(u, default_port) for u in uri]) self.passwd[realm][reduced_uri] = (user, passwd) def find_user_password(self, realm, authuri): domains = self.passwd.get(realm, {}) for default_port in True, False: reduced_authuri = self.reduce_uri(authuri, default_port) for uris, authinfo in domains.iteritems(): for uri in uris: if self.is_suburi(uri, reduced_authuri): return authinfo return None, None def reduce_uri(self, uri, default_port=True): """Accept authority or URI and extract only the authority and path.""" # note HTTP URLs do not have a userinfo component parts = urlparse.urlsplit(uri) if parts[1]: # URI scheme = parts[0] authority = parts[1] path = parts[2] or '/' else: # host or host:port scheme = None authority = uri path = '/' host, port = splitport(authority) if default_port and port is None and scheme is not None: dport = {"http": 80, "https": 443, }.get(scheme) if dport is not None: authority = "%s:%d" % (host, dport) return authority, path def is_suburi(self, base, test): """Check if test is below base in a URI tree Both args must be URIs in reduced form. """ if base == test: return True if base[0] != test[0]: return False common = posixpath.commonprefix((base[1], test[1])) if len(common) == len(base[1]): return True return False class HTTPPasswordMgrWithDefaultRealm(HTTPPasswordMgr): def find_user_password(self, realm, authuri): user, password = HTTPPasswordMgr.find_user_password(self, realm, authuri) if user is not None: return user, password return HTTPPasswordMgr.find_user_password(self, None, authuri) class AbstractBasicAuthHandler: # XXX this allows for multiple auth-schemes, but will stupidly pick # the last one with a realm specified. # allow for double- and single-quoted realm values # (single quotes are a violation of the RFC, but appear in the wild) rx = re.compile('(?:^|,)' # start of the string or ',' '[ \t]*' # optional whitespaces '([^ \t]+)' # scheme like "Basic" '[ \t]+' # mandatory whitespaces # realm=xxx # realm='xxx' # realm="xxx" 'realm=(["\'])(.*?)\\2', re.I) # XXX could pre-emptively send auth info already accepted (RFC 2617, # end of section 2, and section 1.2 immediately after "credentials" # production). def __init__(self, password_mgr=None): if password_mgr is None: password_mgr = HTTPPasswordMgr() self.passwd = password_mgr self.add_password = self.passwd.add_password self.retried = 0 def reset_retry_count(self): self.retried = 0 def http_error_auth_reqed(self, authreq, host, req, headers): # host may be an authority (without userinfo) or a URL with an # authority # XXX could be multiple headers authreq = headers.get(authreq, None) if self.retried > 5: # retry sending the username:password 5 times before failing. raise HTTPError(req.get_full_url(), 401, "basic auth failed", headers, None) else: self.retried += 1 if authreq: mo = AbstractBasicAuthHandler.rx.search(authreq) if mo: scheme, quote, realm = mo.groups() if scheme.lower() == 'basic': return self.retry_http_basic_auth(host, req, realm) def retry_http_basic_auth(self, host, req, realm): user, pw = self.passwd.find_user_password(realm, host) if pw is not None: raw = "%s:%s" % (user, pw) auth = 'Basic %s' % base64.b64encode(raw).strip() if req.headers.get(self.auth_header, None) == auth: return None req.add_unredirected_header(self.auth_header, auth) return self.parent.open(req, timeout=req.timeout) else: return None class HTTPBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler): auth_header = 'Authorization' def http_error_401(self, req, fp, code, msg, headers): url = req.get_full_url() response = self.http_error_auth_reqed('www-authenticate', url, req, headers) self.reset_retry_count() return response class ProxyBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler): auth_header = 'Proxy-authorization' def http_error_407(self, req, fp, code, msg, headers): # http_error_auth_reqed requires that there is no userinfo component in # authority. Assume there isn't one, since urllib2 does not (and # should not, RFC 3986 s. 3.2.1) support requests for URLs containing # userinfo. authority = req.get_host() response = self.http_error_auth_reqed('proxy-authenticate', authority, req, headers) self.reset_retry_count() return response def randombytes(n): """Return n random bytes.""" # Use /dev/urandom if it is available. Fall back to random module # if not. It might be worthwhile to extend this function to use # other platform-specific mechanisms for getting random bytes. if os.path.exists("/dev/urandom"): f = open("/dev/urandom") s = f.read(n) f.close() return s else: L = [chr(random.randrange(0, 256)) for i in range(n)] return "".join(L) class AbstractDigestAuthHandler: # Digest authentication is specified in RFC 2617. # XXX The client does not inspect the Authentication-Info header # in a successful response. # XXX It should be possible to test this implementation against # a mock server that just generates a static set of challenges. # XXX qop="auth-int" supports is shaky def __init__(self, passwd=None): if passwd is None: passwd = HTTPPasswordMgr() self.passwd = passwd self.add_password = self.passwd.add_password self.retried = 0 self.nonce_count = 0 self.last_nonce = None def reset_retry_count(self): self.retried = 0 def http_error_auth_reqed(self, auth_header, host, req, headers): authreq = headers.get(auth_header, None) if self.retried > 5: # Don't fail endlessly - if we failed once, we'll probably # fail a second time. Hm. Unless the Password Manager is # prompting for the information. Crap. This isn't great # but it's better than the current 'repeat until recursion # depth exceeded' approach <wink> raise HTTPError(req.get_full_url(), 401, "digest auth failed", headers, None) else: self.retried += 1 if authreq: scheme = authreq.split()[0] if scheme.lower() == 'digest': return self.retry_http_digest_auth(req, authreq) def retry_http_digest_auth(self, req, auth): token, challenge = auth.split(' ', 1) chal = parse_keqv_list(parse_http_list(challenge)) auth = self.get_authorization(req, chal) if auth: auth_val = 'Digest %s' % auth if req.headers.get(self.auth_header, None) == auth_val: return None req.add_unredirected_header(self.auth_header, auth_val) resp = self.parent.open(req, timeout=req.timeout) return resp def get_cnonce(self, nonce): # The cnonce-value is an opaque # quoted string value provided by the client and used by both client # and server to avoid chosen plaintext attacks, to provide mutual # authentication, and to provide some message integrity protection. # This isn't a fabulous effort, but it's probably Good Enough. dig = hashlib.sha1("%s:%s:%s:%s" % (self.nonce_count, nonce, time.ctime(), randombytes(8))).hexdigest() return dig[:16] def get_authorization(self, req, chal): try: realm = chal['realm'] nonce = chal['nonce'] qop = chal.get('qop') algorithm = chal.get('algorithm', 'MD5') # mod_digest doesn't send an opaque, even though it isn't # supposed to be optional opaque = chal.get('opaque', None) except KeyError: return None H, KD = self.get_algorithm_impls(algorithm) if H is None: return None user, pw = self.passwd.find_user_password(realm, req.get_full_url()) if user is None: return None # XXX not implemented yet if req.has_data(): entdig = self.get_entity_digest(req.get_data(), chal) else: entdig = None A1 = "%s:%s:%s" % (user, realm, pw) A2 = "%s:%s" % (req.get_method(), # XXX selector: what about proxies and full urls req.get_selector()) if qop == 'auth': if nonce == self.last_nonce: self.nonce_count += 1 else: self.nonce_count = 1 self.last_nonce = nonce ncvalue = '%08x' % self.nonce_count cnonce = self.get_cnonce(nonce) noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2)) respdig = KD(H(A1), noncebit) elif qop is None: respdig = KD(H(A1), "%s:%s" % (nonce, H(A2))) else: # XXX handle auth-int. raise URLError("qop '%s' is not supported." % qop) # XXX should the partial digests be encoded too? base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \ 'response="%s"' % (user, realm, nonce, req.get_selector(), respdig) if opaque: base += ', opaque="%s"' % opaque if entdig: base += ', digest="%s"' % entdig base += ', algorithm="%s"' % algorithm if qop: base += ', qop=auth, nc=%s, cnonce="%s"' % (ncvalue, cnonce) return base def get_algorithm_impls(self, algorithm): # algorithm should be case-insensitive according to RFC2617 algorithm = algorithm.upper() # lambdas assume digest modules are imported at the top level if algorithm == 'MD5': H = lambda x: hashlib.md5(x).hexdigest() elif algorithm == 'SHA': H = lambda x: hashlib.sha1(x).hexdigest() # XXX MD5-sess KD = lambda s, d: H("%s:%s" % (s, d)) return H, KD def get_entity_digest(self, data, chal): # XXX not implemented yet return None class HTTPDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler): """An authentication protocol defined by RFC 2069 Digest authentication improves on basic authentication because it does not transmit passwords in the clear. """ auth_header = 'Authorization' handler_order = 490 # before Basic auth def http_error_401(self, req, fp, code, msg, headers): host = urlparse.urlparse(req.get_full_url())[1] retry = self.http_error_auth_reqed('www-authenticate', host, req, headers) self.reset_retry_count() return retry class ProxyDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler): auth_header = 'Proxy-Authorization' handler_order = 490 # before Basic auth def http_error_407(self, req, fp, code, msg, headers): host = req.get_host() retry = self.http_error_auth_reqed('proxy-authenticate', host, req, headers) self.reset_retry_count() return retry class AbstractHTTPHandler(BaseHandler): def __init__(self, debuglevel=0): self._debuglevel = debuglevel def set_http_debuglevel(self, level): self._debuglevel = level def do_request_(self, request): host = request.get_host() if not host: raise URLError('no host given') if request.has_data(): # POST data = request.get_data() if not request.has_header('Content-type'): request.add_unredirected_header( 'Content-type', 'application/x-www-form-urlencoded') if not request.has_header('Content-length'): request.add_unredirected_header( 'Content-length', '%d' % len(data)) sel_host = host if request.has_proxy(): scheme, sel = splittype(request.get_selector()) sel_host, sel_path = splithost(sel) if not request.has_header('Host'): request.add_unredirected_header('Host', sel_host) for name, value in self.parent.addheaders: name = name.capitalize() if not request.has_header(name): request.add_unredirected_header(name, value) return request def do_open(self, http_class, req): """Return an addinfourl object for the request, using http_class. http_class must implement the HTTPConnection API from httplib. The addinfourl return value is a file-like object. It also has methods and attributes including: - info(): return a mimetools.Message object for the headers - geturl(): return the original request URL - code: HTTP status code """ host = req.get_host() if not host: raise URLError('no host given') h = http_class(host, timeout=req.timeout) # will parse host:port h.set_debuglevel(self._debuglevel) headers = dict(req.headers) headers.update(req.unredirected_hdrs) # We want to make an HTTP/1.1 request, but the addinfourl # class isn't prepared to deal with a persistent connection. # It will try to read all remaining data from the socket, # which will block while the server waits for the next request. # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" headers = dict( (name.title(), val) for name, val in headers.items()) if req._tunnel_host: tunnel_headers = {} proxy_auth_hdr = "Proxy-Authorization" if proxy_auth_hdr in headers: tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] # Proxy-Authorization should not be sent to origin # server. del headers[proxy_auth_hdr] h._set_tunnel(req._tunnel_host, headers=tunnel_headers) try: h.request(req.get_method(), req.get_selector(), req.data, headers) r = h.getresponse() except socket.error, err: # XXX what error? raise URLError(err) # Pick apart the HTTPResponse object to get the addinfourl # object initialized properly. # Wrap the HTTPResponse object in socket's file object adapter # for Windows. That adapter calls recv(), so delegate recv() # to read(). This weird wrapping allows the returned object to # have readline() and readlines() methods. # XXX It might be better to extract the read buffering code # out of socket._fileobject() and into a base class. r.recv = r.read fp = socket._fileobject(r, close=True) resp = addinfourl(fp, r.msg, req.get_full_url()) resp.code = r.status resp.msg = r.reason return resp class HTTPHandler(AbstractHTTPHandler): def http_open(self, req): return self.do_open(httplib.HTTPConnection, req) http_request = AbstractHTTPHandler.do_request_ if hasattr(httplib, 'HTTPS'): class HTTPSHandler(AbstractHTTPHandler): def https_open(self, req): return self.do_open(httplib.HTTPSConnection, req) https_request = AbstractHTTPHandler.do_request_ class HTTPCookieProcessor(BaseHandler): def __init__(self, cookiejar=None): import cookielib if cookiejar is None: cookiejar = cookielib.CookieJar() self.cookiejar = cookiejar def http_request(self, request): self.cookiejar.add_cookie_header(request) return request def http_response(self, request, response): self.cookiejar.extract_cookies(response, request) return response https_request = http_request https_response = http_response class UnknownHandler(BaseHandler): def unknown_open(self, req): type = req.get_type() raise URLError('unknown url type: %s' % type) def parse_keqv_list(l): """Parse list of key=value strings where keys are not duplicated.""" parsed = {} for elt in l: k, v = elt.split('=', 1) if v[0] == '"' and v[-1] == '"': v = v[1:-1] parsed[k] = v return parsed def parse_http_list(s): """Parse lists as described by RFC 2068 Section 2. In particular, parse comma-separated lists where the elements of the list may include quoted-strings. A quoted-string could contain a comma. A non-quoted string could have quotes in the middle. Neither commas nor quotes count if they are escaped. Only double-quotes count, not single-quotes. """ res = [] part = '' escape = quote = False for cur in s: if escape: part += cur escape = False continue if quote: if cur == '\\': escape = True continue elif cur == '"': quote = False part += cur continue if cur == ',': res.append(part) part = '' continue if cur == '"': quote = True part += cur # append last part if part: res.append(part) return [part.strip() for part in res] class FileHandler(BaseHandler): # Use local file or FTP depending on form of URL def file_open(self, req): url = req.get_selector() if url[:2] == '//' and url[2:3] != '/' and (req.host and req.host != 'localhost'): req.type = 'ftp' return self.parent.open(req) else: return self.open_local_file(req) # names for the localhost names = None def get_names(self): if FileHandler.names is None: try: FileHandler.names = tuple( socket.gethostbyname_ex('localhost')[2] + socket.gethostbyname_ex(socket.gethostname())[2]) except socket.gaierror: FileHandler.names = (socket.gethostbyname('localhost'),) return FileHandler.names # not entirely sure what the rules are here def open_local_file(self, req): import email.utils import mimetypes host = req.get_host() filename = req.get_selector() localfile = url2pathname(filename) try: stats = os.stat(localfile) size = stats.st_size modified = email.utils.formatdate(stats.st_mtime, usegmt=True) mtype = mimetypes.guess_type(filename)[0] headers = mimetools.Message(StringIO( 'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' % (mtype or 'text/plain', size, modified))) if host: host, port = splitport(host) if not host or \ (not port and socket.gethostbyname(host) in self.get_names()): if host: origurl = 'file://' + host + filename else: origurl = 'file://' + filename return addinfourl(open(localfile, 'rb'), headers, origurl) except OSError, msg: # urllib2 users shouldn't expect OSErrors coming from urlopen() raise URLError(msg) raise URLError('file not on local host') class FTPHandler(BaseHandler): def ftp_open(self, req): import ftplib import mimetypes host = req.get_host() if not host: raise URLError('ftp error: no host given') host, port = splitport(host) if port is None: port = ftplib.FTP_PORT else: port = int(port) # username/password handling user, host = splituser(host) if user: user, passwd = splitpasswd(user) else: passwd = None host = unquote(host) user = unquote(user or '') passwd = unquote(passwd or '') try: host = socket.gethostbyname(host) except socket.error, msg: raise URLError(msg) path, attrs = splitattr(req.get_selector()) dirs = path.split('/') dirs = map(unquote, dirs) dirs, file = dirs[:-1], dirs[-1] if dirs and not dirs[0]: dirs = dirs[1:] try: fw = self.connect_ftp(user, passwd, host, port, dirs, req.timeout) type = file and 'I' or 'D' 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 = fw.retrfile(file, type) headers = "" mtype = mimetypes.guess_type(req.get_full_url())[0] if mtype: headers += "Content-type: %s\n" % mtype if retrlen is not None and retrlen >= 0: headers += "Content-length: %d\n" % retrlen sf = StringIO(headers) headers = mimetools.Message(sf) return addinfourl(fp, headers, req.get_full_url()) except ftplib.all_errors, msg: raise URLError, ('ftp error: %s' % msg), sys.exc_info()[2] def connect_ftp(self, user, passwd, host, port, dirs, timeout): fw = ftpwrapper(user, passwd, host, port, dirs, timeout) ## fw.ftp.set_debuglevel(1) return fw class CacheFTPHandler(FTPHandler): # XXX would be nice to have pluggable cache strategies # XXX this stuff is definitely not thread safe def __init__(self): self.cache = {} self.timeout = {} self.soonest = 0 self.delay = 60 self.max_conns = 16 def setTimeout(self, t): self.delay = t def setMaxConns(self, m): self.max_conns = m def connect_ftp(self, user, passwd, host, port, dirs, timeout): key = user, host, port, '/'.join(dirs), timeout if key in self.cache: self.timeout[key] = time.time() + self.delay else: self.cache[key] = ftpwrapper(user, passwd, host, port, dirs, timeout) self.timeout[key] = time.time() + self.delay self.check_cache() return self.cache[key] def check_cache(self): # first check for old ones t = time.time() if self.soonest <= t: for k, v in self.timeout.items(): if v < t: self.cache[k].close() del self.cache[k] del self.timeout[k] self.soonest = min(self.timeout.values()) # then check the size if len(self.cache) == self.max_conns: for k, v in self.timeout.items(): if v == self.soonest: del self.cache[k] del self.timeout[k] break self.soonest = min(self.timeout.values())
Save
cmd:
run