OLD | NEW |
1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """The task RPC server code. | 5 """The client RPC server code. |
6 | 6 |
7 This server is an XML-RPC server which serves code from | 7 This server is an XML-RPC server which serves code from |
8 rpc_methods.RPCMethods. | 8 client_rpc_methods.RPCMethods. |
9 | 9 |
10 This server will run until shutdown is called on the server object. This can | 10 This server will run until shutdown is called on the server object. This can |
11 be achieved in 2 ways: | 11 be achieved in 2 ways: |
12 | 12 |
13 - Calling the Quit RPC method defined in RPCMethods | 13 - Calling the Quit RPC method defined in RPCMethods |
14 - Not receiving any calls within the idle_timeout_secs time. | 14 - Not receiving any calls within the idle_timeout_secs time. |
15 """ | 15 """ |
16 | 16 |
17 import logging | 17 import logging |
18 import threading | 18 import threading |
19 import time | 19 import time |
20 import xmlrpclib | 20 import xmlrpclib |
21 import SimpleXMLRPCServer | 21 import SimpleXMLRPCServer |
22 import SocketServer | 22 import SocketServer |
23 | 23 |
24 #pylint: disable=relative-import | 24 #pylint: disable=relative-import |
| 25 import client_rpc_methods |
25 import common_lib | 26 import common_lib |
26 import rpc_methods | |
27 | 27 |
28 | 28 |
29 class RequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): | 29 class RequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): |
30 """Restricts access to only specified IP address. | 30 """Restricts access to only specified IP address. |
31 | 31 |
32 This call assumes the server is RPCServer. | 32 This call assumes the server is RPCServer. |
33 """ | 33 """ |
34 | 34 |
35 def do_POST(self): | 35 def do_POST(self): |
36 """Verifies the task is authorized to perform RPCs.""" | 36 """Verifies the client is authorized to perform RPCs.""" |
37 if self.client_address[0] != self.server.authorized_address: | 37 if self.client_address[0] != self.server.authorized_address: |
38 logging.error('Received unauthorized RPC request from %s', | 38 logging.error('Received unauthorized RPC request from %s', |
39 self.task_address[0]) | 39 self.client_address[0]) |
40 self.send_response(403) | 40 self.send_response(403) |
41 response = 'Forbidden' | 41 response = 'Forbidden' |
42 self.send_header('Content-type', 'text/plain') | 42 self.send_header('Content-type', 'text/plain') |
43 self.send_header('Content-length', str(len(response))) | 43 self.send_header('Content-length', str(len(response))) |
44 self.end_headers() | 44 self.end_headers() |
45 self.wfile.write(response) | 45 self.wfile.write(response) |
46 else: | 46 else: |
47 return SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.do_POST(self) | 47 return SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.do_POST(self) |
48 | 48 |
49 | 49 |
50 class RPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer, | 50 class RPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer, |
51 SocketServer.ThreadingMixIn): | 51 SocketServer.ThreadingMixIn): |
52 """Restricts all endpoints to only specified IP addresses.""" | 52 """Restricts all endpoints to only specified IP addresses.""" |
53 | 53 |
54 def __init__(self, authorized_address, | 54 def __init__(self, authorized_address, |
55 idle_timeout_secs=common_lib.DEFAULT_TIMEOUT_SECS): | 55 idle_timeout_secs=common_lib.DEFAULT_TIMEOUT_SECS): |
56 SimpleXMLRPCServer.SimpleXMLRPCServer.__init__( | 56 SimpleXMLRPCServer.SimpleXMLRPCServer.__init__( |
57 self, (common_lib.SERVER_ADDRESS, common_lib.SERVER_PORT), | 57 self, (common_lib.SERVER_ADDRESS, common_lib.SERVER_PORT), |
58 allow_none=True, logRequests=False, | 58 allow_none=True, logRequests=False, |
59 requestHandler=RequestHandler) | 59 requestHandler=RequestHandler) |
60 | 60 |
61 self.authorized_address = authorized_address | 61 self.authorized_address = authorized_address |
62 self.idle_timeout_secs = idle_timeout_secs | 62 self.idle_timeout_secs = idle_timeout_secs |
63 self.register_instance(rpc_methods.RPCMethods(self)) | 63 self.register_instance(client_rpc_methods.RPCMethods(self)) |
64 | 64 |
65 self._shutdown_requested_event = threading.Event() | 65 self._shutdown_requested_event = threading.Event() |
66 self._rpc_received_event = threading.Event() | 66 self._rpc_received_event = threading.Event() |
67 self._idle_thread = threading.Thread(target=self._CheckForIdleQuit) | 67 self._idle_thread = threading.Thread(target=self._CheckForIdleQuit) |
68 | 68 |
69 def shutdown(self): | 69 def shutdown(self): |
70 """Shutdown the server. | 70 """Shutdown the server. |
71 | 71 |
72 This overloaded method sets the _shutdown_requested_event to allow the | 72 This overloaded method sets the _shutdown_requested_event to allow the |
73 idle timeout thread to quit. | 73 idle timeout thread to quit. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 # An external source called shutdown() | 119 # An external source called shutdown() |
120 return | 120 return |
121 elif self._rpc_received_event.is_set(): | 121 elif self._rpc_received_event.is_set(): |
122 logging.debug('Resetting the idle timeout') | 122 logging.debug('Resetting the idle timeout') |
123 timeout = time.time() + self.idle_timeout_secs | 123 timeout = time.time() + self.idle_timeout_secs |
124 self._rpc_received_event.clear() | 124 self._rpc_received_event.clear() |
125 time.sleep(1) | 125 time.sleep(1) |
126 # We timed out, kill the server | 126 # We timed out, kill the server |
127 logging.warning('Shutting down the server due to the idle timeout') | 127 logging.warning('Shutting down the server due to the idle timeout') |
128 self.shutdown() | 128 self.shutdown() |
OLD | NEW |