summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bitbake/lib/bb/server/xmlrpc.py166
1 files changed, 100 insertions, 66 deletions
diff --git a/bitbake/lib/bb/server/xmlrpc.py b/bitbake/lib/bb/server/xmlrpc.py
index ca3a401013..e9c106b20e 100644
--- a/bitbake/lib/bb/server/xmlrpc.py
+++ b/bitbake/lib/bb/server/xmlrpc.py
@@ -54,82 +54,104 @@ if sys.hexversion < 0x020600F0:
54# Upstream Python bug is #8194 (http://bugs.python.org/issue8194) 54# Upstream Python bug is #8194 (http://bugs.python.org/issue8194)
55# This bug is relevant for Python 2.7.0 and 2.7.1 but was fixed for 55# This bug is relevant for Python 2.7.0 and 2.7.1 but was fixed for
56# Python > 2.7.2 56# Python > 2.7.2
57#
58# To implement a simple form of client control, we use a special transport
59# that adds a HTTP header field ("Bitbake-token") to ensure that a server
60# can communicate with only a client at a given time (the client must use
61# the same token).
57## 62##
63if (2, 7, 0) <= sys.version_info < (2, 7, 2):
64 class BBTransport(xmlrpclib.Transport):
65 def __init__(self):
66 self.connection_token = None
67 xmlrpclib.Transport.__init__(self)
68
69 def request(self, host, handler, request_body, verbose=0):
70 h = self.make_connection(host)
71 if verbose:
72 h.set_debuglevel(1)
73
74 self.send_request(h, handler, request_body)
75 self.send_host(h, host)
76 self.send_user_agent(h)
77 if self.connection_token:
78 h.putheader("Bitbake-token", self.connection_token)
79 self.send_content(h, request_body)
80
81 errcode, errmsg, headers = h.getreply()
82
83 if errcode != 200:
84 raise ProtocolError(
85 host + handler,
86 errcode, errmsg,
87 headers
88 )
89
90 self.verbose = verbose
58 91
59class BBTransport(xmlrpclib.Transport): 92 try:
60 def request(self, host, handler, request_body, verbose=0): 93 sock = h._conn.sock
61 h = self.make_connection(host) 94 except AttributeError:
62 if verbose: 95 sock = None
63 h.set_debuglevel(1) 96
64 97 return self._parse_response(h.getfile(), sock)
65 self.send_request(h, handler, request_body) 98
66 self.send_host(h, host) 99 def make_connection(self, host):
67 self.send_user_agent(h) 100 import httplib
68 self.send_content(h, request_body) 101 host, extra_headers, x509 = self.get_host_info(host)
69 102 return httplib.HTTP(host)
70 errcode, errmsg, headers = h.getreply() 103
71 104 def _parse_response(self, file, sock):
72 if errcode != 200: 105 p, u = self.getparser()
73 raise ProtocolError( 106
74 host + handler, 107 while 1:
75 errcode, errmsg, 108 if sock:
76 headers 109 response = sock.recv(1024)
77 ) 110 else:
78 111 response = file.read(1024)
79 self.verbose = verbose 112 if not response:
80 113 break
81 try: 114 if self.verbose:
82 sock = h._conn.sock 115 print("body:", repr(response))
83 except AttributeError: 116 p.feed(response)
84 sock = None 117
85 118 file.close()
86 return self._parse_response(h.getfile(), sock) 119 p.close()
87 120
88 def make_connection(self, host): 121 return u.close()
89 import httplib 122
90 host, extra_headers, x509 = self.get_host_info(host) 123 def set_connection_token(self, token):
91 return httplib.HTTP(host) 124 self.connection_token = token
92 125else:
93 def _parse_response(self, file, sock): 126 class BBTransport(xmlrpclib.Transport):
94 p, u = self.getparser() 127 def __init__(self):
95 128 self.connection_token = None
96 while 1: 129 xmlrpclib.Transport.__init__(self)
97 if sock: 130
98 response = sock.recv(1024) 131 def set_connection_token(self, token):
99 else: 132 self.connection_token = token
100 response = file.read(1024) 133
101 if not response: 134 def send_content(self, h, body):
102 break 135 if self.connection_token:
103 if self.verbose: 136 h.putheader("Bitbake-token", self.connection_token)
104 print("body:", repr(response)) 137 xmlrpclib.Transport.send_content(self, h, body)
105 p.feed(response)
106
107 file.close()
108 p.close()
109
110 return u.close()
111 138
112def _create_server(host, port): 139def _create_server(host, port):
113 # Python 2.7.0 and 2.7.1 have a buggy Transport implementation 140 t = BBTransport()
114 # For those versions of Python, and only those versions, use our 141 s = xmlrpclib.Server("http://%s:%d/" % (host, port), transport=t, allow_none=True)
115 # own copy/paste BBTransport class. 142 return s, t
116 if (2, 7, 0) <= sys.version_info < (2, 7, 2):
117 t = BBTransport()
118 s = xmlrpclib.Server("http://%s:%d/" % (host, port), transport=t, allow_none=True)
119 else:
120 s = xmlrpclib.Server("http://%s:%d/" % (host, port), allow_none=True)
121
122 return s
123 143
124class BitBakeServerCommands(): 144class BitBakeServerCommands():
145
125 def __init__(self, server): 146 def __init__(self, server):
126 self.server = server 147 self.server = server
148 self.has_client = False
127 149
128 def registerEventHandler(self, host, port): 150 def registerEventHandler(self, host, port):
129 """ 151 """
130 Register a remote UI Event Handler 152 Register a remote UI Event Handler
131 """ 153 """
132 s = _create_server(host, port) 154 s, t = _create_server(host, port)
133 155
134 return bb.event.register_UIHhandler(s) 156 return bb.event.register_UIHhandler(s)
135 157
@@ -248,10 +270,22 @@ class BitbakeServerInfo():
248 270
249class BitBakeServerConnection(): 271class BitBakeServerConnection():
250 def __init__(self, serverinfo, clientinfo=("localhost", 0)): 272 def __init__(self, serverinfo, clientinfo=("localhost", 0)):
251 self.connection = _create_server(serverinfo.host, serverinfo.port) 273 self.connection, self.transport = _create_server(serverinfo.host, serverinfo.port)
252 self.events = uievent.BBUIEventQueue(self.connection, clientinfo) 274 self.clientinfo = clientinfo
275 self.serverinfo = serverinfo
276
277 def connect(self):
278 token = self.connection.addClient()
279 if token is None:
280 return None
281 self.transport.set_connection_token(token)
282 self.events = uievent.BBUIEventQueue(self.connection, self.clientinfo)
253 for event in bb.event.ui_queue: 283 for event in bb.event.ui_queue:
254 self.events.queue_event(event) 284 self.events.queue_event(event)
285 return self
286
287 def removeClient(self):
288 self.connection.removeClient()
255 289
256 def terminate(self): 290 def terminate(self):
257 # Don't wait for server indefinitely 291 # Don't wait for server indefinitely
@@ -277,7 +311,7 @@ class BitBakeServer(object):
277 def getServerIdleCB(self): 311 def getServerIdleCB(self):
278 return self.server.register_idle_function 312 return self.server.register_idle_function
279 313
280 def saveConnectionDetails(self): 314 def saveConnectionDetails(self):
281 self.serverinfo = BitbakeServerInfo(self.server.host, self.server.port) 315 self.serverinfo = BitbakeServerInfo(self.server.host, self.server.port)
282 316
283 def detach(self): 317 def detach(self):