]> git.lizzy.rs Git - plan9front.git/blob - sys/lib/python/hgext/hgwebfs.py
hgwebfs: simplify retry loop construction
[plan9front.git] / sys / lib / python / hgext / hgwebfs.py
1 ''' webfs support '''
2
3 import mercurial.url
4 import re
5 import os
6
7 class Webconn:
8         def __init__(self, mnt, req):
9                 while True:
10                         try:
11                                 self.open(mnt, req)
12                                 return
13                         except IOError, e:
14                                 try:
15                                         errstr = e.strerror
16                                         params = errstr[errstr.index("needkey ")+8:]
17                                         if params.find("!password?") < 0:
18                                                 raise e
19                                         if os.spawnl(os.P_WAIT, "/boot/factotum", "getkey", "-g", params) != 0:
20                                                 raise e
21                                 except:
22                                         raise e
23
24         def open(self, mnt, req):
25                 if type(req) == str:
26                         self.url = req
27                 else:
28                         self.url = req.get_full_url()
29                 if self.url[0:5] == 'file:':
30                         path = self.url[5:]
31                         while path[0:2] == '//':
32                                 path = path[1:]
33                         self.dir = '/dev/null'
34                         self.body = open(path, 'r', 0)
35                         return
36                 ctl = open(mnt+'/clone', 'r+', 0)
37                 try:
38                         self.dir = mnt+'/'+ctl.readline().rstrip('\n')
39                         ctl.seek(0)
40                         ctl.write('url '+self.url)
41                         m = 'User-Agent: mercurial/proto-1.0\r\n';
42                         for h in req.headers:
43                                 m += h+': '+req.headers[h]+'\r\n'
44                         ctl.seek(0)
45                         ctl.write('headers '+m)
46                         if req.has_data():
47                                 data = req.get_data()
48                                 post = open(self.dir+'/postbody', 'w', 0);
49                                 try:
50                                         data.seek(0)
51                                         while True:
52                                                 buf = data.read(4096)
53                                                 if len(buf) == 0:
54                                                         break
55                                                 post.write(buf)
56                                 finally:
57                                         post.close()
58                         self.body = open(self.dir+'/body', 'r', 0)
59                 finally:        
60                         ctl.close()
61
62         def read(self, amt=4096):
63                 return self.body.read(amt);
64
65         def close(self):
66                 self.body.close()
67                 self.body = None
68                 self.dir = None
69
70         def geturl(self):
71                 return self.url
72
73         def getheader(self, key):
74                 name = re.sub(r'[^a-z]+', '', key.lower())
75                 try:
76                         f = open(self.dir+'/'+name, 'r', 0)
77                         try:
78                                 hdr = f.read()
79                         finally:
80                                 f.close()
81                         return hdr
82                 except:
83                         return None
84
85 class Webopener:
86         def __init__(self):
87                 self.handlers = []
88
89         def add_handler(self, handler):
90                 return
91
92         def open(self, req, data=None):
93                 return Webconn('/mnt/web', req)
94
95         def close(self):
96                 pass
97
98
99 def webopener(ui, authinfo=None):
100         return Webopener();
101
102 mercurial.url.has_https = 1
103 mercurial.url.opener = webopener