22 def is_throttled (address): |
22 def is_throttled (address): |
23 i = 0 |
23 i = 0 |
24 |
24 |
25 while i < len (g_throttle): |
25 while i < len (g_throttle): |
26 if g_throttle[i][1] <= datetime.utcnow(): |
26 if g_throttle[i][1] <= datetime.utcnow(): |
27 print 'Throttle of %s expired' % g_throttle[i][0][0] |
27 print 'Throttle of %s expired' % g_throttle[i][0] |
28 item = g_throttle.pop (i) # expired |
28 item = g_throttle.pop (i) # expired |
29 |
29 |
30 if item[0][0] == address[0]: |
30 if item[0] == address: |
31 return False # this address expired |
31 return False # this address expired |
32 |
32 |
33 continue |
33 continue |
34 |
34 |
35 if g_throttle[i][0][0] == address[0]: |
35 if g_throttle[i][0] == address: |
36 return True # is throttled |
36 return True # is throttled |
37 |
37 |
38 i += 1 |
38 i += 1 |
39 |
39 |
40 return False # not throttled |
40 return False # not throttled |
51 |
51 |
52 Irc.broadcast ('Throttling %s:%s for 30 seconds' % address) |
52 Irc.broadcast ('Throttling %s:%s for 30 seconds' % address) |
53 |
53 |
54 def handle_rest_http (data, address): |
54 def handle_rest_http (data, address): |
55 global g_credentials |
55 global g_credentials |
56 displayaddress = '%s:%s' % address |
56 displayaddress = address |
57 authrex = re.compile (r'^authorization: Basic (.+)$') |
57 authrex = re.compile (r'^authorization: Basic (.+)$') |
58 payloadrex = re.compile (r'^payload=(.+)$') |
58 payloadrex = re.compile (r'^payload=(.+)$') |
59 authenticated = False |
59 authenticated = False |
60 payload = '' |
60 payload = '' |
61 |
61 |
82 jsonstring = urllib.unquote_plus (payload).decode ('utf-8') |
82 jsonstring = urllib.unquote_plus (payload).decode ('utf-8') |
83 |
83 |
84 try: |
84 try: |
85 jsondata = json.loads (jsonstring) |
85 jsondata = json.loads (jsonstring) |
86 repodata = jsondata['repository'] |
86 repodata = jsondata['repository'] |
87 repopath = '%s/%s' % (repodata['owner'], repodata['name'] |
87 repopath = '%s/%s' % (repodata['owner'], repodata['name']) |
88 |
88 |
89 if repopath not in valid_repos: |
89 if repopath not in valid_repos: |
90 raise ValueError ('unknown repository %s' % repopath) |
90 raise ValueError ('unknown repository %s' % repopath) |
91 |
91 |
92 if 'commits' in jsondata: |
92 if 'commits' in jsondata: |
106 throttle (address) |
106 throttle (address) |
107 return |
107 return |
108 |
108 |
109 class RESTConnection (asyncore.dispatcher): |
109 class RESTConnection (asyncore.dispatcher): |
110 httpdata = '' |
110 httpdata = '' |
111 address=None |
|
112 writebuffer = '' |
111 writebuffer = '' |
|
112 address = None |
113 |
113 |
114 def __init__ (self, conn, address): |
114 def __init__ (self, conn, address): |
115 asyncore.dispatcher.__init__ (self, conn) |
115 asyncore.dispatcher.__init__ (self, conn) |
116 self.socket = ssl.wrap_socket (conn, server_side=True, keyfile='key.pem', |
116 self.socket = ssl.wrap_socket (conn, server_side=True, keyfile='key.pem', |
117 certfile='cert.pem', do_handshake_on_connect=False) |
117 certfile='cert.pem', do_handshake_on_connect=False) |
118 self.socket.setblocking (0) |
118 self.socket.setblocking (0) |
119 self.address = address |
119 self.address = address |
|
120 print 'Initialized connection handler for %s' % type (address) |
120 |
121 |
121 while True: |
122 while True: |
122 try: |
123 try: |
123 self.socket.do_handshake() |
124 self.socket.do_handshake() |
124 break |
125 break |
126 if err.args[0] == ssl.SSL_ERROR_WANT_READ: |
127 if err.args[0] == ssl.SSL_ERROR_WANT_READ: |
127 select.select([self.socket], [], []) |
128 select.select([self.socket], [], []) |
128 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE: |
129 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE: |
129 select.select([], [self.socket], []) |
130 select.select([], [self.socket], []) |
130 else: |
131 else: |
131 Irc.broadcast ('%s:%s: SSL error: %s' % (self.address[0], self.address[1], err)) |
132 Irc.broadcast ('%s:%s: SSL error: %s' % (self.address[0], err)) |
132 throttle (self.address) |
133 throttle (self.address[0]) |
133 self.close() |
134 self.close() |
134 return |
135 return |
135 |
136 |
136 def write (self, msg): |
137 def write (self, msg): |
137 self.writebuffer += msg |
138 self.writebuffer += msg |
147 |
148 |
148 def handle_read (self): |
149 def handle_read (self): |
149 while 1: |
150 while 1: |
150 try: |
151 try: |
151 data = self.recv (4096) |
152 data = self.recv (4096) |
152 except ssl.SSLError, err: |
153 except: |
153 # EOF |
154 # EOF |
154 self.finish() |
155 self.finish() |
155 return |
156 return |
156 |
157 |
157 self.httpdata += data.replace ('\r', '') |
158 self.httpdata += data.replace ('\r', '') |
158 |
159 |
159 def finish (self): |
160 def finish (self): |
160 handle_rest_http (self.httpdata.split ('\n'), self.address) |
161 handle_rest_http (self.httpdata.split ('\n'), self.address[0]) |
161 self.close() |
162 self.close() |
162 |
163 |
163 def handle_write (self): |
164 def handle_write (self): |
164 self.send (self.writebuffer) |
165 self.send (self.writebuffer) |
165 self.writebuffer='' |
166 self.writebuffer='' |
174 if g_portnumber == None: |
175 if g_portnumber == None: |
175 g_portnumber = Config.get_node ('rest').get_value ('port') |
176 g_portnumber = Config.get_node ('rest').get_value ('port') |
176 |
177 |
177 asyncore.dispatcher.__init__ (self) |
178 asyncore.dispatcher.__init__ (self) |
178 self.create_socket (socket.AF_INET, socket.SOCK_STREAM) |
179 self.create_socket (socket.AF_INET, socket.SOCK_STREAM) |
|
180 self.setsockopt (socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) |
179 self.bind (('', g_portnumber)) |
181 self.bind (('', g_portnumber)) |
180 self.listen (5) |
182 self.listen (5) |
181 print 'REST server initialized' |
183 print 'REST server initialized' |
182 |
184 |
183 def handle_accept (self): |
185 def handle_accept (self): |