Linux server.edchosting.com 4.18.0-553.79.1.lve.el7h.x86_64 #1 SMP Wed Oct 15 16:34:46 UTC 2025 x86_64
LiteSpeed
Server IP : 75.98.162.185 & Your IP : 216.73.216.163
Domains :
Cant Read [ /etc/named.conf ]
User : goons4good
Terminal
Auto Root
Create File
Create Folder
Localroot Suggester
Backdoor Destroyer
Readme
/
usr /
lib64 /
python2.7 /
site-packages /
mercurial /
Delete
Unzip
Name
Size
Permission
Date
Action
help
[ DIR ]
drwxr-xr-x
2021-09-16 10:54
hgweb
[ DIR ]
drwxr-xr-x
2021-09-16 10:54
httpclient
[ DIR ]
drwxr-xr-x
2021-09-16 10:54
templates
[ DIR ]
drwxr-xr-x
2021-09-16 10:54
__init__.py
0
B
-rw-r--r--
2013-06-01 18:10
__init__.pyc
143
B
-rw-r--r--
2020-03-31 23:33
__init__.pyo
143
B
-rw-r--r--
2020-03-31 23:33
__version__.py
59
B
-rw-r--r--
2013-06-01 18:10
__version__.pyc
174
B
-rw-r--r--
2020-03-31 23:33
__version__.pyo
174
B
-rw-r--r--
2020-03-31 23:33
ancestor.py
12.62
KB
-rw-r--r--
2013-06-01 18:10
ancestor.pyc
9.1
KB
-rw-r--r--
2020-03-31 23:33
ancestor.pyo
9.1
KB
-rw-r--r--
2020-03-31 23:33
archival.py
10.15
KB
-rw-r--r--
2013-06-01 18:10
archival.pyc
12.62
KB
-rw-r--r--
2020-03-31 23:33
archival.pyo
12.62
KB
-rw-r--r--
2020-03-31 23:33
base85.so
11.05
KB
-rwxr-xr-x
2020-03-31 23:33
bdiff.so
15.23
KB
-rwxr-xr-x
2020-03-31 23:33
bookmarks.py
9.44
KB
-rw-r--r--
2013-06-01 18:10
bookmarks.pyc
9.4
KB
-rw-r--r--
2020-03-31 23:33
bookmarks.pyo
9.4
KB
-rw-r--r--
2020-03-31 23:33
branchmap.py
8.74
KB
-rw-r--r--
2013-06-01 18:10
branchmap.pyc
7.53
KB
-rw-r--r--
2020-03-31 23:33
branchmap.pyo
7.48
KB
-rw-r--r--
2020-03-31 23:33
bundlerepo.py
13.38
KB
-rw-r--r--
2013-06-01 18:10
bundlerepo.pyc
13.36
KB
-rw-r--r--
2020-03-31 23:33
bundlerepo.pyo
13.36
KB
-rw-r--r--
2020-03-31 23:33
byterange.py
16.14
KB
-rw-r--r--
2013-06-01 18:10
byterange.pyc
14.98
KB
-rw-r--r--
2020-03-31 23:33
byterange.pyo
14.83
KB
-rw-r--r--
2020-03-31 23:33
changegroup.py
8.09
KB
-rw-r--r--
2013-06-01 18:10
changegroup.pyc
11.1
KB
-rw-r--r--
2020-03-31 23:33
changegroup.pyo
11.1
KB
-rw-r--r--
2020-03-31 23:33
changelog.py
11.75
KB
-rw-r--r--
2013-06-01 18:10
changelog.pyc
14.08
KB
-rw-r--r--
2020-03-31 23:33
changelog.pyo
14.04
KB
-rw-r--r--
2020-03-31 23:33
cmdutil.py
75.63
KB
-rw-r--r--
2020-03-31 23:33
cmdutil.pyc
64.09
KB
-rw-r--r--
2020-03-31 23:33
cmdutil.pyo
64.09
KB
-rw-r--r--
2020-03-31 23:33
commands.py
211.62
KB
-rw-r--r--
2013-06-01 18:10
commands.pyc
197.58
KB
-rw-r--r--
2020-03-31 23:33
commands.pyo
197.53
KB
-rw-r--r--
2020-03-31 23:33
commandserver.py
6.56
KB
-rw-r--r--
2013-06-01 18:10
commandserver.pyc
7.48
KB
-rw-r--r--
2020-03-31 23:33
commandserver.pyo
7.44
KB
-rw-r--r--
2020-03-31 23:33
config.py
6.57
KB
-rw-r--r--
2013-06-01 18:10
config.pyc
8.15
KB
-rw-r--r--
2020-03-31 23:33
config.pyo
8.15
KB
-rw-r--r--
2020-03-31 23:33
context.py
44.46
KB
-rw-r--r--
2020-03-31 23:33
context.pyc
59.66
KB
-rw-r--r--
2020-03-31 23:33
context.pyo
59.43
KB
-rw-r--r--
2020-03-31 23:33
copies.py
12.04
KB
-rw-r--r--
2013-06-01 18:10
copies.pyc
9.19
KB
-rw-r--r--
2020-03-31 23:33
copies.pyo
9.19
KB
-rw-r--r--
2020-03-31 23:33
dagparser.py
14.4
KB
-rw-r--r--
2013-06-01 18:10
dagparser.pyc
12.92
KB
-rw-r--r--
2020-03-31 23:33
dagparser.pyo
12.92
KB
-rw-r--r--
2020-03-31 23:33
dagutil.py
8.04
KB
-rw-r--r--
2013-06-01 18:10
dagutil.pyc
11.31
KB
-rw-r--r--
2020-03-31 23:33
dagutil.pyo
11.21
KB
-rw-r--r--
2020-03-31 23:33
demandimport.py
5.13
KB
-rw-r--r--
2013-06-01 18:10
demandimport.pyc
5.17
KB
-rw-r--r--
2020-03-31 23:33
demandimport.pyo
5.17
KB
-rw-r--r--
2020-03-31 23:33
dicthelpers.py
1.58
KB
-rw-r--r--
2013-06-01 18:10
dicthelpers.pyc
1.59
KB
-rw-r--r--
2020-03-31 23:33
dicthelpers.pyo
1.59
KB
-rw-r--r--
2020-03-31 23:33
diffhelpers.so
11.18
KB
-rwxr-xr-x
2020-03-31 23:33
dirstate.py
27.42
KB
-rw-r--r--
2020-03-31 23:33
dirstate.pyc
25.63
KB
-rw-r--r--
2020-03-31 23:33
dirstate.pyo
25.63
KB
-rw-r--r--
2020-03-31 23:33
discovery.py
13.38
KB
-rw-r--r--
2013-06-01 18:10
discovery.pyc
11.35
KB
-rw-r--r--
2020-03-31 23:33
discovery.pyo
11.35
KB
-rw-r--r--
2020-03-31 23:33
dispatch.py
31.68
KB
-rw-r--r--
2020-03-31 23:33
dispatch.pyc
27.9
KB
-rw-r--r--
2020-03-31 23:33
dispatch.pyo
27.9
KB
-rw-r--r--
2020-03-31 23:33
encoding.py
9.36
KB
-rw-r--r--
2013-06-01 18:10
encoding.pyc
9.96
KB
-rw-r--r--
2020-03-31 23:33
encoding.pyo
9.96
KB
-rw-r--r--
2020-03-31 23:33
error.py
2.68
KB
-rw-r--r--
2013-06-01 18:10
error.pyc
6.36
KB
-rw-r--r--
2020-03-31 23:33
error.pyo
6.36
KB
-rw-r--r--
2020-03-31 23:33
extensions.py
10.69
KB
-rw-r--r--
2013-06-01 18:10
extensions.pyc
11.3
KB
-rw-r--r--
2020-03-31 23:33
extensions.pyo
11.15
KB
-rw-r--r--
2020-03-31 23:33
fancyopts.py
3.48
KB
-rw-r--r--
2013-06-01 18:10
fancyopts.pyc
2.95
KB
-rw-r--r--
2020-03-31 23:33
fancyopts.pyo
2.95
KB
-rw-r--r--
2020-03-31 23:33
filelog.py
2.69
KB
-rw-r--r--
2013-06-01 18:10
filelog.pyc
3.59
KB
-rw-r--r--
2020-03-31 23:33
filelog.pyo
3.59
KB
-rw-r--r--
2020-03-31 23:33
filemerge.py
12.55
KB
-rw-r--r--
2013-06-01 18:10
filemerge.pyc
13.13
KB
-rw-r--r--
2020-03-31 23:33
filemerge.pyo
13.13
KB
-rw-r--r--
2020-03-31 23:33
fileset.py
14.92
KB
-rw-r--r--
2013-06-01 18:10
fileset.pyc
20.04
KB
-rw-r--r--
2020-03-31 23:33
fileset.pyo
20.04
KB
-rw-r--r--
2020-03-31 23:33
formatter.py
2.79
KB
-rw-r--r--
2013-06-01 18:10
formatter.pyc
5.5
KB
-rw-r--r--
2020-03-31 23:33
formatter.pyo
5.5
KB
-rw-r--r--
2020-03-31 23:33
graphmod.py
11.79
KB
-rw-r--r--
2013-06-01 18:10
graphmod.pyc
10.08
KB
-rw-r--r--
2020-03-31 23:33
graphmod.pyo
10.02
KB
-rw-r--r--
2020-03-31 23:33
hbisect.py
9.01
KB
-rw-r--r--
2013-06-01 18:10
hbisect.pyc
6.59
KB
-rw-r--r--
2020-03-31 23:33
hbisect.pyo
6.55
KB
-rw-r--r--
2020-03-31 23:33
help.py
17.6
KB
-rw-r--r--
2013-06-01 18:10
help.pyc
16.02
KB
-rw-r--r--
2020-03-31 23:33
help.pyo
16.02
KB
-rw-r--r--
2020-03-31 23:33
hg.py
21.44
KB
-rw-r--r--
2013-06-01 18:10
hg.pyc
20.09
KB
-rw-r--r--
2020-03-31 23:33
hg.pyo
20.09
KB
-rw-r--r--
2020-03-31 23:33
hook.py
7.7
KB
-rw-r--r--
2013-06-01 18:10
hook.pyc
6.56
KB
-rw-r--r--
2020-03-31 23:33
hook.pyo
6.56
KB
-rw-r--r--
2020-03-31 23:33
httpconnection.py
10.66
KB
-rw-r--r--
2013-06-01 18:10
httpconnection.pyc
9.32
KB
-rw-r--r--
2020-03-31 23:33
httpconnection.pyo
9.32
KB
-rw-r--r--
2020-03-31 23:33
httppeer.py
9.08
KB
-rw-r--r--
2013-06-01 18:10
httppeer.pyc
9.36
KB
-rw-r--r--
2020-03-31 23:33
httppeer.pyo
9.36
KB
-rw-r--r--
2020-03-31 23:33
i18n.py
2.1
KB
-rw-r--r--
2020-03-31 23:33
i18n.pyc
1.86
KB
-rw-r--r--
2020-03-31 23:33
i18n.pyo
1.86
KB
-rw-r--r--
2020-03-31 23:33
ignore.py
3.48
KB
-rw-r--r--
2013-06-01 18:10
ignore.pyc
3.25
KB
-rw-r--r--
2020-03-31 23:33
ignore.pyo
3.25
KB
-rw-r--r--
2020-03-31 23:33
keepalive.py
25.31
KB
-rw-r--r--
2013-06-01 18:10
keepalive.pyc
21.97
KB
-rw-r--r--
2020-03-31 23:33
keepalive.pyo
21.97
KB
-rw-r--r--
2020-03-31 23:33
localrepo.py
99.89
KB
-rw-r--r--
2020-03-31 23:33
localrepo.pyc
83.39
KB
-rw-r--r--
2020-03-31 23:33
localrepo.pyo
83.34
KB
-rw-r--r--
2020-03-31 23:33
lock.py
4.81
KB
-rw-r--r--
2013-06-01 18:10
lock.pyc
4.57
KB
-rw-r--r--
2020-03-31 23:33
lock.pyo
4.57
KB
-rw-r--r--
2020-03-31 23:33
lsprof.py
3.59
KB
-rw-r--r--
2013-06-01 18:10
lsprof.pyc
4.47
KB
-rw-r--r--
2020-03-31 23:33
lsprof.pyo
4.47
KB
-rw-r--r--
2020-03-31 23:33
lsprofcalltree.py
2.7
KB
-rw-r--r--
2013-06-01 18:10
lsprofcalltree.pyc
2.99
KB
-rw-r--r--
2020-03-31 23:33
lsprofcalltree.pyo
2.99
KB
-rw-r--r--
2020-03-31 23:33
mail.py
12.21
KB
-rw-r--r--
2013-06-01 18:10
mail.pyc
13.48
KB
-rw-r--r--
2020-03-31 23:33
mail.pyo
13.48
KB
-rw-r--r--
2020-03-31 23:33
manifest.py
7.95
KB
-rw-r--r--
2013-06-01 18:10
manifest.pyc
8.03
KB
-rw-r--r--
2020-03-31 23:33
manifest.pyo
8.03
KB
-rw-r--r--
2020-03-31 23:33
match.py
10.73
KB
-rw-r--r--
2013-06-01 18:10
match.pyc
13.96
KB
-rw-r--r--
2020-03-31 23:33
match.pyo
13.96
KB
-rw-r--r--
2020-03-31 23:33
mdiff.py
11.34
KB
-rw-r--r--
2013-06-01 18:10
mdiff.pyc
11.04
KB
-rw-r--r--
2020-03-31 23:33
mdiff.pyo
11.04
KB
-rw-r--r--
2020-03-31 23:33
merge.py
27.73
KB
-rw-r--r--
2013-06-01 18:10
merge.pyc
23.22
KB
-rw-r--r--
2020-03-31 23:33
merge.pyo
23.12
KB
-rw-r--r--
2020-03-31 23:33
minirst.py
23.93
KB
-rw-r--r--
2013-06-01 18:10
minirst.pyc
20.82
KB
-rw-r--r--
2020-03-31 23:33
minirst.pyo
20.82
KB
-rw-r--r--
2020-03-31 23:33
mpatch.so
11.17
KB
-rwxr-xr-x
2020-03-31 23:33
node.py
449
B
-rw-r--r--
2013-06-01 18:10
node.pyc
483
B
-rw-r--r--
2020-03-31 23:33
node.pyo
483
B
-rw-r--r--
2020-03-31 23:33
obsolete.py
29.41
KB
-rw-r--r--
2013-06-01 18:10
obsolete.pyc
25.01
KB
-rw-r--r--
2020-03-31 23:33
obsolete.pyo
24.97
KB
-rw-r--r--
2020-03-31 23:33
osutil.so
16.07
KB
-rwxr-xr-x
2020-03-31 23:33
parser.py
3.67
KB
-rw-r--r--
2013-06-01 18:10
parser.pyc
3.32
KB
-rw-r--r--
2020-03-31 23:33
parser.pyo
3.32
KB
-rw-r--r--
2020-03-31 23:33
parsers.so
45.55
KB
-rwxr-xr-x
2020-03-31 23:33
patch.py
63.88
KB
-rw-r--r--
2013-06-01 18:10
patch.pyc
59.85
KB
-rw-r--r--
2020-03-31 23:33
patch.pyo
59.85
KB
-rw-r--r--
2020-03-31 23:33
peer.py
1.32
KB
-rw-r--r--
2013-06-01 18:10
peer.pyc
1.96
KB
-rw-r--r--
2020-03-31 23:33
peer.pyo
1.96
KB
-rw-r--r--
2020-03-31 23:33
phases.py
14.37
KB
-rw-r--r--
2013-06-01 18:10
phases.pyc
13.55
KB
-rw-r--r--
2020-03-31 23:33
phases.pyo
13.55
KB
-rw-r--r--
2020-03-31 23:33
posix.py
18.95
KB
-rw-r--r--
2020-03-31 23:33
posix.pyc
21.35
KB
-rw-r--r--
2020-03-31 23:33
posix.pyo
21.35
KB
-rw-r--r--
2020-03-31 23:33
pushkey.py
1.13
KB
-rw-r--r--
2013-06-01 18:10
pushkey.pyc
1.99
KB
-rw-r--r--
2020-03-31 23:33
pushkey.pyo
1.99
KB
-rw-r--r--
2020-03-31 23:33
pvec.py
5.85
KB
-rw-r--r--
2013-06-01 18:10
pvec.pyc
7.36
KB
-rw-r--r--
2020-03-31 23:33
pvec.pyo
7.36
KB
-rw-r--r--
2020-03-31 23:33
py3kcompat.py
2.31
KB
-rw-r--r--
2013-06-01 18:10
py3kcompat.pyc
1.9
KB
-rw-r--r--
2020-03-31 23:33
py3kcompat.pyo
1.9
KB
-rw-r--r--
2020-03-31 23:33
repair.py
6.02
KB
-rw-r--r--
2013-06-01 18:10
repair.pyc
5.12
KB
-rw-r--r--
2020-03-31 23:33
repair.pyo
5.12
KB
-rw-r--r--
2020-03-31 23:33
repoview.py
8.49
KB
-rw-r--r--
2013-06-01 18:10
repoview.pyc
9.2
KB
-rw-r--r--
2020-03-31 23:33
repoview.pyo
9.06
KB
-rw-r--r--
2020-03-31 23:33
revlog.py
44.66
KB
-rw-r--r--
2013-06-01 18:10
revlog.pyc
38.92
KB
-rw-r--r--
2020-03-31 23:33
revlog.pyo
38.86
KB
-rw-r--r--
2020-03-31 23:33
revset.py
61.17
KB
-rw-r--r--
2013-06-01 18:10
revset.pyc
67.28
KB
-rw-r--r--
2020-03-31 23:33
revset.pyo
67.28
KB
-rw-r--r--
2020-03-31 23:33
scmposix.py
877
B
-rw-r--r--
2013-06-01 18:10
scmposix.pyc
1.43
KB
-rw-r--r--
2020-03-31 23:33
scmposix.pyo
1.43
KB
-rw-r--r--
2020-03-31 23:33
scmutil.py
31.78
KB
-rw-r--r--
2020-03-31 23:33
scmutil.pyc
35.55
KB
-rw-r--r--
2020-03-31 23:33
scmutil.pyo
35.45
KB
-rw-r--r--
2020-03-31 23:33
scmwindows.py
1.63
KB
-rw-r--r--
2013-06-01 18:10
scmwindows.pyc
1.79
KB
-rw-r--r--
2020-03-31 23:33
scmwindows.pyo
1.79
KB
-rw-r--r--
2020-03-31 23:33
setdiscovery.py
6.73
KB
-rw-r--r--
2013-06-01 18:10
setdiscovery.pyc
5.2
KB
-rw-r--r--
2020-03-31 23:33
setdiscovery.pyo
5.17
KB
-rw-r--r--
2020-03-31 23:33
similar.py
3.56
KB
-rw-r--r--
2013-06-01 18:10
similar.pyc
3.32
KB
-rw-r--r--
2020-03-31 23:33
similar.pyo
3.32
KB
-rw-r--r--
2020-03-31 23:33
simplemerge.py
14.93
KB
-rw-r--r--
2013-06-01 18:10
simplemerge.pyc
12.2
KB
-rw-r--r--
2020-03-31 23:33
simplemerge.pyo
11.77
KB
-rw-r--r--
2020-03-31 23:33
sshpeer.py
7.22
KB
-rw-r--r--
2020-03-31 23:33
sshpeer.pyc
8.78
KB
-rw-r--r--
2020-03-31 23:33
sshpeer.pyo
8.78
KB
-rw-r--r--
2020-03-31 23:33
sshserver.py
4.17
KB
-rw-r--r--
2013-06-01 18:10
sshserver.pyc
5.77
KB
-rw-r--r--
2020-03-31 23:33
sshserver.pyo
5.77
KB
-rw-r--r--
2020-03-31 23:33
sslutil.py
6.49
KB
-rw-r--r--
2013-06-01 18:10
sslutil.pyc
5.57
KB
-rw-r--r--
2020-03-31 23:33
sslutil.pyo
5.57
KB
-rw-r--r--
2020-03-31 23:33
statichttprepo.py
5.05
KB
-rw-r--r--
2013-06-01 18:10
statichttprepo.pyc
7.04
KB
-rw-r--r--
2020-03-31 23:33
statichttprepo.pyo
7.04
KB
-rw-r--r--
2020-03-31 23:33
store.py
16.47
KB
-rw-r--r--
2013-06-01 18:10
store.pyc
20.56
KB
-rw-r--r--
2020-03-31 23:33
store.pyo
20.56
KB
-rw-r--r--
2020-03-31 23:33
strutil.py
913
B
-rw-r--r--
2013-06-01 18:10
strutil.pyc
978
B
-rw-r--r--
2020-03-31 23:33
strutil.pyo
978
B
-rw-r--r--
2020-03-31 23:33
subrepo.py
54.68
KB
-rw-r--r--
2020-03-31 23:33
subrepo.pyc
52.89
KB
-rw-r--r--
2020-03-31 23:33
subrepo.pyo
52.89
KB
-rw-r--r--
2020-03-31 23:33
tags.py
11.22
KB
-rw-r--r--
2013-06-01 18:10
tags.pyc
6.89
KB
-rw-r--r--
2020-03-31 23:33
tags.pyo
6.39
KB
-rw-r--r--
2020-03-31 23:33
templatefilters.py
12.66
KB
-rw-r--r--
2013-06-01 18:10
templatefilters.pyc
17.98
KB
-rw-r--r--
2020-03-31 23:33
templatefilters.pyo
17.98
KB
-rw-r--r--
2020-03-31 23:33
templatekw.py
12.92
KB
-rw-r--r--
2013-06-01 18:10
templatekw.pyc
16.5
KB
-rw-r--r--
2020-03-31 23:33
templatekw.pyo
16.5
KB
-rw-r--r--
2020-03-31 23:33
templater.py
16.28
KB
-rw-r--r--
2013-06-01 18:10
templater.pyc
18.12
KB
-rw-r--r--
2020-03-31 23:33
templater.pyo
18.12
KB
-rw-r--r--
2020-03-31 23:33
transaction.py
5.09
KB
-rw-r--r--
2013-06-01 18:10
transaction.pyc
6.34
KB
-rw-r--r--
2020-03-31 23:33
transaction.pyo
6.34
KB
-rw-r--r--
2020-03-31 23:33
treediscovery.py
5.05
KB
-rw-r--r--
2013-06-01 18:10
treediscovery.pyc
3.67
KB
-rw-r--r--
2020-03-31 23:33
treediscovery.pyo
3.67
KB
-rw-r--r--
2020-03-31 23:33
ui.py
29.33
KB
-rw-r--r--
2013-06-01 18:10
ui.pyc
28.88
KB
-rw-r--r--
2020-03-31 23:33
ui.pyo
28.88
KB
-rw-r--r--
2020-03-31 23:33
unionrepo.py
7.27
KB
-rw-r--r--
2013-06-01 18:10
unionrepo.pyc
8.85
KB
-rw-r--r--
2020-03-31 23:33
unionrepo.pyo
8.82
KB
-rw-r--r--
2020-03-31 23:33
url.py
17.08
KB
-rw-r--r--
2013-06-01 18:10
url.pyc
15.91
KB
-rw-r--r--
2020-03-31 23:33
url.pyo
15.91
KB
-rw-r--r--
2020-03-31 23:33
util.py
60.48
KB
-rw-r--r--
2020-03-31 23:33
util.pyc
63.22
KB
-rw-r--r--
2020-03-31 23:33
util.pyo
63.14
KB
-rw-r--r--
2020-03-31 23:33
verify.py
10.68
KB
-rw-r--r--
2013-06-01 18:10
verify.pyc
9.37
KB
-rw-r--r--
2020-03-31 23:33
verify.pyo
9.37
KB
-rw-r--r--
2020-03-31 23:33
win32.py
13.64
KB
-rw-r--r--
2013-06-01 18:10
win32.pyc
11.5
KB
-rw-r--r--
2020-03-31 23:33
win32.pyo
11.5
KB
-rw-r--r--
2020-03-31 23:33
windows.py
10.76
KB
-rw-r--r--
2020-03-31 23:33
windows.pyc
14.12
KB
-rw-r--r--
2020-03-31 23:33
windows.pyo
14.12
KB
-rw-r--r--
2020-03-31 23:33
wireproto.py
22.98
KB
-rw-r--r--
2020-03-31 23:33
wireproto.pyc
27.79
KB
-rw-r--r--
2020-03-31 23:33
wireproto.pyo
27.79
KB
-rw-r--r--
2020-03-31 23:33
worker.py
4.4
KB
-rw-r--r--
2013-06-01 18:10
worker.pyc
5.31
KB
-rw-r--r--
2020-03-31 23:33
worker.pyo
5.31
KB
-rw-r--r--
2020-03-31 23:33
Save
Rename
# httppeer.py - HTTP repository proxy classes for mercurial # # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. from node import nullid from i18n import _ import changegroup, statichttprepo, error, httpconnection, url, util, wireproto import os, urllib, urllib2, zlib, httplib import errno, socket def zgenerator(f): zd = zlib.decompressobj() try: for chunk in util.filechunkiter(f): while chunk: yield zd.decompress(chunk, 2**18) chunk = zd.unconsumed_tail except httplib.HTTPException: raise IOError(None, _('connection ended unexpectedly')) yield zd.flush() class httppeer(wireproto.wirepeer): def __init__(self, ui, path): self.path = path self.caps = None self.handler = None self.urlopener = None u = util.url(path) if u.query or u.fragment: raise util.Abort(_('unsupported URL component: "%s"') % (u.query or u.fragment)) # urllib cannot handle URLs with embedded user or passwd self._url, authinfo = u.authinfo() self.ui = ui self.ui.debug('using %s\n' % self._url) self.urlopener = url.opener(ui, authinfo) def __del__(self): if self.urlopener: for h in self.urlopener.handlers: h.close() getattr(h, "close_all", lambda : None)() def url(self): return self.path # look up capabilities only when needed def _fetchcaps(self): self.caps = set(self._call('capabilities').split()) def _capabilities(self): if self.caps is None: try: self._fetchcaps() except error.RepoError: self.caps = set() self.ui.debug('capabilities: %s\n' % (' '.join(self.caps or ['none']))) return self.caps def lock(self): raise util.Abort(_('operation not supported over http')) def _callstream(self, cmd, **args): if cmd == 'pushkey': args['data'] = '' data = args.pop('data', None) size = 0 if util.safehasattr(data, 'length'): size = data.length elif data is not None: size = len(data) headers = args.pop('headers', {}) if data is not None and 'Content-Type' not in headers: headers['Content-Type'] = 'application/mercurial-0.1' if size and self.ui.configbool('ui', 'usehttp2', False): headers['Expect'] = '100-Continue' headers['X-HgHttp2'] = '1' self.ui.debug("sending %s command\n" % cmd) q = [('cmd', cmd)] headersize = 0 if len(args) > 0: httpheader = self.capable('httpheader') if httpheader: headersize = int(httpheader.split(',')[0]) if headersize > 0: # The headers can typically carry more data than the URL. encargs = urllib.urlencode(sorted(args.items())) headerfmt = 'X-HgArg-%s' contentlen = headersize - len(headerfmt % '000' + ': \r\n') headernum = 0 for i in xrange(0, len(encargs), contentlen): headernum += 1 header = headerfmt % str(headernum) headers[header] = encargs[i:i + contentlen] varyheaders = [headerfmt % str(h) for h in range(1, headernum + 1)] headers['Vary'] = ','.join(varyheaders) else: q += sorted(args.items()) qs = '?%s' % urllib.urlencode(q) cu = "%s%s" % (self._url, qs) req = urllib2.Request(cu, data, headers) if data is not None: self.ui.debug("sending %s bytes\n" % size) req.add_unredirected_header('Content-Length', '%d' % size) try: resp = self.urlopener.open(req) except urllib2.HTTPError, inst: if inst.code == 401: raise util.Abort(_('authorization failed')) raise except httplib.HTTPException, inst: self.ui.debug('http error while sending %s command\n' % cmd) self.ui.traceback() raise IOError(None, inst) except IndexError: # this only happens with Python 2.3, later versions raise URLError raise util.Abort(_('http error, possibly caused by proxy setting')) # record the url we got redirected to resp_url = resp.geturl() if resp_url.endswith(qs): resp_url = resp_url[:-len(qs)] if self._url.rstrip('/') != resp_url.rstrip('/'): if not self.ui.quiet: self.ui.warn(_('real URL is %s\n') % resp_url) self._url = resp_url try: proto = resp.getheader('content-type') except AttributeError: proto = resp.headers.get('content-type', '') safeurl = util.hidepassword(self._url) if proto.startswith('application/hg-error'): raise error.OutOfBandError(resp.read()) # accept old "text/plain" and "application/hg-changegroup" for now if not (proto.startswith('application/mercurial-') or (proto.startswith('text/plain') and not resp.headers.get('content-length')) or proto.startswith('application/hg-changegroup')): self.ui.debug("requested URL: '%s'\n" % util.hidepassword(cu)) raise error.RepoError( _("'%s' does not appear to be an hg repository:\n" "---%%<--- (%s)\n%s\n---%%<---\n") % (safeurl, proto or 'no content-type', resp.read(1024))) if proto.startswith('application/mercurial-'): try: version = proto.split('-', 1)[1] version_info = tuple([int(n) for n in version.split('.')]) except ValueError: raise error.RepoError(_("'%s' sent a broken Content-Type " "header (%s)") % (safeurl, proto)) if version_info > (0, 1): raise error.RepoError(_("'%s' uses newer protocol %s") % (safeurl, version)) return resp def _call(self, cmd, **args): fp = self._callstream(cmd, **args) try: return fp.read() finally: # if using keepalive, allow connection to be reused fp.close() def _callpush(self, cmd, cg, **args): # have to stream bundle to a temp file because we do not have # http 1.1 chunked transfer. types = self.capable('unbundle') try: types = types.split(',') except AttributeError: # servers older than d1b16a746db6 will send 'unbundle' as a # boolean capability. They only support headerless/uncompressed # bundles. types = [""] for x in types: if x in changegroup.bundletypes: type = x break tempname = changegroup.writebundle(cg, None, type) fp = httpconnection.httpsendfile(self.ui, tempname, "rb") headers = {'Content-Type': 'application/mercurial-0.1'} try: try: r = self._call(cmd, data=fp, headers=headers, **args) vals = r.split('\n', 1) if len(vals) < 2: raise error.ResponseError(_("unexpected response:"), r) return vals except socket.error, err: if err.args[0] in (errno.ECONNRESET, errno.EPIPE): raise util.Abort(_('push failed: %s') % err.args[1]) raise util.Abort(err.args[1]) finally: fp.close() os.unlink(tempname) def _abort(self, exception): raise exception def _decompress(self, stream): return util.chunkbuffer(zgenerator(stream)) class httpspeer(httppeer): def __init__(self, ui, path): if not url.has_https: raise util.Abort(_('Python support for SSL and HTTPS ' 'is not installed')) httppeer.__init__(self, ui, path) def instance(ui, path, create): if create: raise util.Abort(_('cannot create new http repository')) try: if path.startswith('https:'): inst = httpspeer(ui, path) else: inst = httppeer(ui, path) try: # Try to do useful work when checking compatibility. # Usually saves a roundtrip since we want the caps anyway. inst._fetchcaps() except error.RepoError: # No luck, try older compatibility check. inst.between([(nullid, nullid)]) return inst except error.RepoError, httpexception: try: r = statichttprepo.instance(ui, "static-" + path, create) ui.note('(falling back to static-http)\n') return r except error.RepoError: raise httpexception # use the original http RepoError instead