9
9
from scscp .scscp import SCSCPQuit , SCSCPProtocolError
10
10
from scscp import scscp
11
11
12
+ from scscp .socketserver import SCSCPServerRequestHandler , SCSCPSocketServer
13
+
12
14
MitMBase = "http://opendreamkit.org/MitM"
13
15
MitMCD = "computation"
14
16
MitMEval = "sage_eval"
15
17
16
- class MitMRequestHandler (socketserver .BaseRequestHandler ):
17
- def __init__ (self ,converter , * kargs , ** kwargs ):
18
+ class MitMRequestHandler (SCSCPServerRequestHandler ):
19
+ def __init__ (self , converter , * args , ** kwargs ):
20
+ super (MitMRequestHandler , self ).__init__ (* args , ** kwargs )
18
21
self .converter = converter
19
- super (socketserver .BaseRequestHandler , self ).__init__ (* kargs , ** kwargs )
20
22
21
- def setup (self ):
22
- self .server .log .info ("New connection from %s:%d" % self .client_address )
23
- self .log = self .server .log .getChild (self .client_address [0 ])
24
- self .scscp = SCSCPServer (self .request , self .server .name ,
25
- self .server .version , logger = self .log )
26
-
27
- # TODO: should be inherited from a to-be-written SCSCPRequestHandler class
28
- def handle (self ):
29
- self .scscp .accept ()
30
- while True :
31
- try :
32
- call = self .scscp .wait ()
33
- except TimeoutError :
34
- continue
35
- except SCSCPQuit as e :
36
- self .log .info (e )
37
- break
38
- except ConnectionResetError :
39
- self .log .info ('Client closed unexpectedly.' )
40
- break
41
- except SCSCPProtocolError as e :
42
- self .log .info ('SCSCP protocol error: %s.' % str (e ))
43
- self .log .info ('Closing connection.' )
44
- self .scscp .quit ()
45
- break
46
- self .handle_call (call )
47
-
48
- # TODO: most of this should be inherited as well
49
- def handle_call (self , call ):
50
- if (call .type != 'procedure_call' ):
51
- raise SCSCPProtocolError ('Bad message from client: %s.' % call .type , om = call .om ())
52
- try :
53
- head = call .data .elem .name
54
- self .log .debug ('Requested head: %s...' % head )
55
-
56
- if call .data .elem .cd == 'scscp2' and head in CD_SCSCP2 :
57
- res = getattr (self , head )(call .data )
58
- elif self .data .elem .base == MitMBase and self .data .elem .cd == MitMCD and self .data .elem .name == MitMEval :
23
+ def handle_call (self , call , head ):
24
+ if self .data .elem .base == MitMBase and self .data .elem .cd == MitMCD and self .data .elem .name == MitMEval :
59
25
# we take the one argument of MitMEval, import it (which triggers computation), and export it (i.e., the result of the computation)
60
26
obj = call .data .arguments [0 ]
61
27
objPy = self .converter .to_python (obj )
62
- res = self .converter .to_openmath (objPy )
63
- else :
64
- self .log .debug ('...head unknown.' )
65
- return self .scscp .terminated (call .id , om .OMError (
66
- om .OMSymbol ('unhandled_symbol' , cd = 'error' ), [call .data .elem ]))
67
-
68
- strlog = str (res )
69
- self .log .debug ('...sending result: %s' % (strlog [:20 ] + ('...' if len (strlog ) > 20 else '' )))
70
- return self .scscp .completed (call .id , res )
71
- except (AttributeError , IndexError , TypeError ):
72
- self .log .debug ('...client protocol error.' )
73
- return self .scscp .terminated (call .id , om .OMError (
74
- om .OMSymbol ('unexpected_symbol' , cd = 'error' ), [call .data ]))
75
- except Exception as e :
76
- self .log .exception ('Unhandled exception:' )
77
- return self .scscp .terminated (call .id , 'system_specific' ,
78
- 'Unhandled exception %s.' % str (e ))
28
+ return self .converter .to_openmath (objPy )
29
+
30
+ return super (MitMRequestHandler , self ).handle_call (call , head )
79
31
80
32
def get_allowed_heads (self , data ):
81
33
return scscp .symbol_set ([om .OMSymbol (base = MitMEval , cd = MitMCD , name = MitMEval )], cdnames = [MitMCD , 'scscp1' ])
@@ -90,27 +42,27 @@ def get_service_description(self, data):
90
42
self .server .version .decode (),
91
43
self .server .description )
92
44
93
- class MitMSCSCPServer (socketserver .ThreadingMixIn , socketserver .TCPServer , object ):
94
- allow_reuse_address = True
95
-
45
+ class MitMSCSCPServer (SCSCPSocketServer ):
96
46
def __init__ (self , openmath_converter , host = 'localhost' , port = 26133 ,
97
47
logger = None , name = b'MitM Server' , version = b'none' ,
98
48
description = 'MitM SCSCP server' ):
99
- # ThreadingMixIn expects a class as constructor argument, so we have to build one that knows about the converter
49
+
50
+ # build a converter class
100
51
class ReqHandler (MitMRequestHandler ):
101
52
def __init__ (self , * args , ** kwargs ):
102
53
super (MitMRequestHandler ,self ).__init__ (openmath_converter , * args , ** kwargs )
103
- super (MitMSCSCPServer , self ).__init__ ((host , port ), ReqHandler )
104
- self .log = logger or logging .getLogger (__name__ )
105
- self .name = name
106
- self .version = version
107
- self .description = description
54
+
55
+ super (MitMSCSCPServer , self ).__init__ (host = host , port = port ,
56
+ logger = logger or logging .getLogger (__name__ ), name = name , version = version ,
57
+ description = description , RequestHandlerClass = ReqHandler )
108
58
109
59
if __name__ == '__main__' :
110
60
logging .basicConfig (level = logging .DEBUG )
111
61
logger = logging .getLogger ('demo_server' )
62
+
112
63
conv = MitMConverter ()
113
64
srv = MitMSCSCPServer (conv , logger = logger )
65
+
114
66
try :
115
67
srv .serve_forever ()
116
68
except KeyboardInterrupt :
0 commit comments