File: ChildProcessServer.py

package info (click to toggle)
boa-constructor 0.3.0-3
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 8,188 kB
  • ctags: 8,857
  • sloc: python: 54,163; sh: 66; makefile: 36
file content (126 lines) | stat: -rw-r--r-- 3,671 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import sys, os, time
import random, sha, threading
from time import sleep
from SocketServer import TCPServer

from IsolatedDebugger import DebugServer, DebuggerConnection
from Tasks import ThreadedTaskHandler

# The process uses the Debugger dir as the main script dir
# here we add the boa root so that Boa modules can be imported.
boa_root = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
if boa_root not in sys.path:
    sys.path.insert(0, boa_root)

from ExternalLib.xmlrpcserver import RequestHandler



serving = 1

debug_server = None
connection = None
auth_str = ''
task_handler = ThreadedTaskHandler()


class DebugRequestHandler (RequestHandler):

    def _authenticate(self):
        h = self.headers
        if auth_str and (not h.has_key('x-auth')
                         or h['x-auth'] != auth_str):
            raise 'Unauthorized', 'X-Auth header missing or incorrect'

    def call(self, method, params):
        # Override of xmlrpcserver.RequestHandler.call()
        self._authenticate()
        if method == 'exit_debugger':
            global serving
            serving = 0
            return 1
        else:
            m = getattr(connection, method)
            result = apply(m, params)
            if result is None:
                result = 0
            return result

    def log_message(self, format, *args):
        pass


class TaskingMixIn:
    """Mix-in class to handle each request in a task thread."""

    def process_request(self, request, client_address):
        """Start a task to process the request."""
        task_handler.addTask(self.finish_request,
                             args=(request, client_address))

class TaskingTCPServer(TaskingMixIn, TCPServer): pass


def streamFlushThread():
    while 1:
        sys.stdout.flush()
        sys.stderr.flush()
        sleep(0.15)  # 150 ms


def main(args=None):
    global auth_str, debug_server, connection, serving

    # Create the debug server.
    if args is None:
        args = sys.argv[1:]
    if args and '--zope' in args:
        from ZopeScriptDebugServer import ZopeScriptDebugServer
        debug_server = ZopeScriptDebugServer()
    else:
        debug_server = DebugServer()
    connection = DebuggerConnection(debug_server)
    connection.allowEnvChanges()  # Allow changing of sys.path, etc.

    # Create an authentication string, always 40 characters.
    auth_str = sha.new(str(random.random())).hexdigest()

    # port is 0 to allocate any port.
    server = TaskingTCPServer(('', 0), DebugRequestHandler)
    port = int(server.socket.getsockname()[1])

    # Tell the client what port to connect to and the auth string to send.
    sys.stdout.write('%010d %s%s' % (port, auth_str, os.linesep))
    sys.stdout.flush()

    # Provide a hard breakpoint hook.  Use it like this:
    # if hasattr(sys, 'breakpoint'): sys.breakpoint()
    sys.breakpoint = debug_server.set_trace
    sys.debugger_control = debug_server
    sys.boa_debugger = debug_server

    def serve_forever(server):
        while 1:
            server.handle_request()

    def startDaemon(target, args=()):
        t = threading.Thread(target=target, args=args)
        t.setDaemon(1)
        t.start()

    startDaemon(serve_forever, (server,))
    startDaemon(streamFlushThread)
    startDaemon(debug_server.servicerThread)

    # Serve until the stdin pipe closes.
    #print 'serving until stdin returns EOF'
    #sys.stdin.read()

    while serving:
        time.sleep(0.1)

    sys.exit(0)


if __name__ == '__main__':
    main()