Drop NetRPC and activate JSON-RPC by default

This commit is contained in:
Cédric Krier
2011-08-06 14:31:24 +02:00
parent 0de081096f
commit d5efbc62ad
10 changed files with 123 additions and 565 deletions
+1
View File
@@ -1,3 +1,4 @@
* Drop NetRPC and activate JSON-RPC by default
* Remove ir.action.wizard_size
* Rename expand and fill attributes into yexpand and yfill
* Add xalign and yalign as field attributes
+1 -10
View File
@@ -9,18 +9,13 @@
# If empty, the server will listen on all available interfaces
#interface =
# Activate the netrpc protocol
#netrpc = True
# Configure the port for the netrpc protocol to listen
#netport = 8070
# Activate the xml-rpc protocol
#xmlrpc = False
# Configure the port for the xml-rpc protocol to listen
#xmlport = 8069
# Activate the json-rpc protocol
#jsonrpc = False
#jsonrpc = True
# Configure the port for the json-rpc protocol to listen
#jsonport = 8000
# Configure the path of json-rpc data
@@ -57,7 +52,6 @@
#logfile = False
# Enable secure connection with SSL
#secure_netrpc = False
#secure_xmlrpc = False
#secure_jsonrpc = False
#secure_webdav = False
@@ -75,9 +69,6 @@
# Configure the path to store attachments and sqlite database
#data_path = /var/lib/trytond
# Limit the number of threads
#max_thread = 40
# Allow to run more than one instance of trytond
#multi_server = False
+1 -5
View File
@@ -8,11 +8,9 @@ class ConfigManager(object):
self.options = {
'hostname': None,
'interface': '',
'netrpc': True,
'netport': 8070,
'xmlrpc': False,
'xmlport': 8069,
'jsonrpc': False,
'jsonrpc': True,
'jsonport': 8000,
'jsondata_path': '/var/www/localhost/tryton',
'webdav': False,
@@ -31,7 +29,6 @@ class ConfigManager(object):
'debug_mode': False,
'pidfile': None,
'logfile': None,
'secure_netrpc': False,
'secure_xmlrpc': False,
'secure_jsonrpc': False,
'secure_webdav': False,
@@ -44,7 +41,6 @@ class ConfigManager(object):
'smtp_user': False,
'smtp_password': False,
'data_path': '/var/lib/trytond',
'max_thread': 40,
'multi_server': False,
'session_timeout': 600,
'psyco': False,
+97 -6
View File
@@ -4,6 +4,13 @@ import errno
import os
import socket
import threading
import select
import sys
import gzip
try:
import cStringIO as StringIO
except ImportError:
import StringIO
def endsocket(sock):
if os.name != 'nt':
@@ -17,7 +24,6 @@ class daemon(threading.Thread):
def __init__(self, interface, port, secure, name=None):
threading.Thread.__init__(self, name=name)
self.secure = secure
self.running = False
self.ipv6 = False
if socket.has_ipv6:
try:
@@ -27,11 +33,96 @@ class daemon(threading.Thread):
pass
def stop(self):
self.running = False
self.server.shutdown()
return
def run(self):
self.running = True
while self.running:
self.server.handle_request()
endsocket(self.server.socket)
self.server.serve_forever()
return True
class GZipRequestHandlerMixin:
if sys.version_info[:2] <= (2, 6):
# Copy from SimpleXMLRPCServer.py with gzip encoding added
def do_POST(self):
"""Handles the HTTP POST request.
Attempts to interpret all HTTP POST requests as XML-RPC calls,
which are forwarded to the server's _dispatch method for handling.
"""
# Check that the path is legal
if not self.is_rpc_path_valid():
self.report_404()
return
try:
# Get arguments by reading body of request.
# We read this in chunks to avoid straining
# socket.read(); around the 10 or 15Mb mark, some platforms
# begin to have problems (bug #792570).
max_chunk_size = 10*1024*1024
size_remaining = int(self.headers["content-length"])
L = []
while size_remaining:
chunk_size = min(size_remaining, max_chunk_size)
L.append(self.rfile.read(chunk_size))
size_remaining -= len(L[-1])
data = ''.join(L)
data = self.decode_request_content(data)
if data is None:
return #response has been sent
# In previous versions of SimpleXMLRPCServer, _dispatch
# could be overridden in this class, instead of in
# SimpleXMLRPCDispatcher. To maintain backwards compatibility,
# check to see if a subclass implements _dispatch and dispatch
# using that method if present.
response = self.server._marshaled_dispatch(
data, getattr(self, '_dispatch', None)
)
except Exception: # This should only happen if the module is buggy
# internal error, report as HTTP server error
self.send_response(500)
self.end_headers()
else:
# got a valid XML RPC response
self.send_response(200)
self.send_header("Content-type", "text/xml")
# Handle gzip encoding
if 'gzip' in self.headers.get('Accept-Encoding', '').split(',') \
and len(response) > self.encode_threshold:
buffer = StringIO.StringIO()
output = gzip.GzipFile(mode='wb', fileobj=buffer)
output.write(response)
output.close()
buffer.seek(0)
response = buffer.getvalue()
self.send_header('Content-Encoding', 'gzip')
self.send_header("Content-length", str(len(response)))
self.end_headers()
self.wfile.write(response)
def decode_request_content(self, data):
#support gzip encoding of request
encoding = self.headers.get("content-encoding", "identity").lower()
if encoding == "identity":
return data
if encoding == "gzip":
f = StringIO.StringIO(data)
gzf = gzip.GzipFile(mode="rb", fileobj=f)
try:
decoded = gzf.read()
except IOError:
self.send_response(400, "error decoding gzip content")
f.close()
gzf.close()
return decoded
else:
self.send_response(501, "encoding %r not supported" % encoding)
self.send_header("Content-length", "0")
self.end_headers()
+18 -71
View File
@@ -4,7 +4,7 @@ from trytond.protocols.sslsocket import SSLSocket
from trytond.protocols.dispatcher import dispatch
from trytond.config import CONFIG
from trytond.protocols.datatype import Float
from trytond.protocols.common import daemon
from trytond.protocols.common import daemon, GZipRequestHandlerMixin
import SimpleXMLRPCServer
import SimpleHTTPServer
import SocketServer
@@ -12,8 +12,6 @@ import traceback
import socket
import sys
import os
import gzip
import StringIO
try:
import fcntl
except ImportError:
@@ -31,6 +29,8 @@ def object_hook(dct):
dct['hour'], dct['minute'], dct['second'])
elif dct['__class__'] == 'date':
return datetime.date(dct['year'], dct['month'], dct['day'])
elif dct['__class__'] == 'Decimal':
return Decimal(dct['decimal'])
return dct
class JSONEncoder(json.JSONEncoder):
@@ -52,7 +52,9 @@ class JSONEncoder(json.JSONEncoder):
'day': obj.day,
}
elif isinstance(obj, Decimal):
return float(obj)
return {'__class__': 'Decimal',
'decimal': str(obj),
}
return super(JSONEncoder, self).default(obj)
@@ -64,7 +66,7 @@ class SimpleJSONRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
reason to instantiate this class directly.
"""
def _marshaled_dispatch(self, data, dispatch_method=None):
def _marshaled_dispatch(self, data, dispatch_method=None, path=None):
"""Dispatches an JSON-RPC method from marshalled (JSON) data.
JSON-RPC methods are dispatched from the marshalled (JSON) data
@@ -75,7 +77,7 @@ class SimpleJSONRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
existing method through subclassing is the prefered means
of changing method dispatch behavior.
"""
rawreq = json.loads(data, object_hook=object_hook, parse_float=Float)
rawreq = json.loads(data, object_hook=object_hook)
req_id = rawreq.get('id', 0)
method = rawreq['method']
@@ -104,7 +106,7 @@ class SimpleJSONRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
traceb = sys.exc_info()[2]
pdb.post_mortem(traceb)
# report exception back to server
response['error'] = "%s:\n%s" % (sys.exc_value, tb_s)
response['error'] = (str(sys.exc_value), tb_s)
return json.dumps(response, cls=JSONEncoder)
@@ -126,7 +128,8 @@ class GenericJSONRPCRequestHandler:
return res
class SimpleJSONRPCRequestHandler(GenericJSONRPCRequestHandler,
class SimpleJSONRPCRequestHandler(GZipRequestHandlerMixin,
GenericJSONRPCRequestHandler,
SimpleXMLRPCServer.SimpleXMLRPCRequestHandler,
SimpleHTTPServer.SimpleHTTPRequestHandler):
"""Simple JSON-RPC request handler class.
@@ -134,71 +137,15 @@ class SimpleJSONRPCRequestHandler(GenericJSONRPCRequestHandler,
Handles all HTTP POST requests and attempts to decode them as
JSON-RPC requests.
"""
protocol_version = "HTTP/1.1"
rpc_paths = None
encode_threshold = 1400 # common MTU
# Copy from SimpleXMLRPCServer.py with gzip encoding added
def do_POST(self):
"""Handles the HTTP POST request.
Attempts to interpret all HTTP POST requests as JSON-RPC calls,
which are forwarded to the server's _dispatch method for handling.
"""
# Check that the path is legal
if not self.is_rpc_path_valid():
self.report_404()
return
try:
# Get arguments by reading body of request.
# We read this in chunks to avoid straining
# socket.read(); around the 10 or 15Mb mark, some platforms
# begin to have problems (bug #792570).
max_chunk_size = 10*1024*1024
size_remaining = int(self.headers["content-length"])
L = []
while size_remaining:
chunk_size = min(size_remaining, max_chunk_size)
L.append(self.rfile.read(chunk_size))
size_remaining -= len(L[-1])
data = ''.join(L)
# In previous versions of SimpleXMLRPCServer, _dispatch
# could be overridden in this class, instead of in
# SimpleXMLRPCDispatcher. To maintain backwards compatibility,
# check to see if a subclass implements _dispatch and dispatch
# using that method if present.
response = self.server._marshaled_dispatch(
data, getattr(self, '_dispatch', None)
)
except Exception: # This should only happen if the module is buggy
# internal error, report as HTTP server error
self.send_response(500)
self.end_headers()
else:
# got a valid JSON RPC response
self.send_response(200)
self.send_header("Content-type", "application/json-rpc")
# Handle gzip encoding
if 'gzip' in self.headers.get('Accept-Encoding', '').split(',') \
and len(response) > self.encode_threshold:
buffer = StringIO.StringIO()
output = gzip.GzipFile(mode='wb', fileobj=buffer)
output.write(response)
output.close()
buffer.seek(0)
response = buffer.getvalue()
self.send_header('Content-Encoding', 'gzip')
self.send_header("Content-length", str(len(response)))
self.end_headers()
self.wfile.write(response)
# shut down the connection
self.wfile.flush()
self.connection.shutdown(1)
def send_header(self, keyword, value):
if keyword == 'Content-type' and value == 'text/xml':
value = 'application/json-rpc'
SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.send_header(self,
keyword, value)
def translate_path(self, path):
"""Translate a /-separated PATH to the local filename syntax.
@@ -274,6 +221,7 @@ class SimpleJSONRPCServer(SocketServer.TCPServer,
class SimpleThreadedJSONRPCServer(SocketServer.ThreadingMixIn,
SimpleJSONRPCServer):
timeout = 1
daemon_threads = True
def server_bind(self):
self.socket.setsockopt(socket.SOL_SOCKET,
@@ -304,7 +252,6 @@ class JSONRPCDaemon(daemon):
def __init__(self, interface, port, secure=False):
daemon.__init__(self, interface, port, secure, name='JSONRPCDaemon')
if self.secure:
handler_class = SecureJSONRPCRequestHandler
server_class = SecureThreadedJSONRPCServer
-139
View File
@@ -1,139 +0,0 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from trytond.pysocket import PySocket
from trytond.protocols.sslsocket import SSLSocket
from trytond.config import CONFIG
from trytond.protocols.dispatcher import dispatch
from trytond.protocols.common import endsocket
import threading
import select
import traceback
import socket
import sys
class NetRPCClientThread(threading.Thread):
def __init__(self, sock, threads, secure):
threading.Thread.__init__(self, name='NetRPCClientThread')
self.sock = sock
self.threads = threads
self.running = False
self.secure = secure
def run(self):
self.running = True
try:
pysocket = PySocket(self.sock)
except Exception:
self.sock.close()
self.threads.remove(self)
return False
timeout = 0
while self.running:
try:
rlist, _, _ = select.select([self.sock], [], [], 1)
except select.error:
continue
if not rlist:
timeout += 1
if timeout > 600:
break
continue
timeout = 0
try:
msg = pysocket.receive()
except Exception:
pysocket.disconnect()
self.threads.remove(self)
return False
host, port = self.sock.getpeername()[:2]
try:
res = dispatch(host, port, 'NetRPC', *msg)
pysocket.send(res)
except Exception, exception:
tb_s = ''
for line in traceback.format_exception(*sys.exc_info()):
try:
line = line.encode('utf-8', 'ignore')
except Exception:
continue
tb_s += line
for path in sys.path:
tb_s = tb_s.replace(path, '')
if CONFIG['debug_mode']:
import pdb
tback = sys.exc_info()[2]
pdb.post_mortem(tback)
try:
pysocket.send(exception.args, exception=True,
traceback=tb_s)
except Exception:
pysocket.disconnect()
self.threads.remove(self)
return False
pysocket.disconnect()
self.threads.remove(self)
return True
def stop(self):
self.running = False
class NetRPCServerThread(threading.Thread):
def __init__(self, interface, port, secure=False):
threading.Thread.__init__(self, name='NetRPCServerThread')
self.socket = None
if socket.has_ipv6:
try:
socket.getaddrinfo(interface or None, port, socket.AF_INET6)
self.socket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
except Exception:
pass
if self.socket is None:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if secure:
self.socket = SSLSocket(self.socket)
self.socket.bind((interface, port))
self.socket.listen(5)
self.threads = []
self.secure = secure
self.running = False
def run(self):
try:
self.running = True
while self.running:
if not int(CONFIG['max_thread']) \
or len(self.threads) < int(CONFIG['max_thread']):
try:
rlist, _, _ = select.select([self.socket], [], [], 1)
except select.error:
continue
if not rlist:
continue
(clientsocket, _) = self.socket.accept()
c_thread = NetRPCClientThread(clientsocket, self.threads,
self.secure)
self.threads.append(c_thread)
c_thread.start()
except Exception:
try:
self.socket.close()
except Exception:
pass
return False
def stop(self):
self.running = False
while len(self.threads):
try:
thread = self.threads[0]
thread.stop()
thread.join()
except Exception:
pass
try:
endsocket(self.socket)
except Exception:
return False
-1
View File
@@ -78,7 +78,6 @@ if not hasattr(WebDAVServer.DAVRequestHandler, '_config'):
class BaseThreadedHTTPServer(SocketServer.ThreadingMixIn,
BaseHTTPServer.HTTPServer):
timeout = 1
max_children = CONFIG['max_thread']
def server_bind(self):
self.socket.setsockopt(socket.SOL_SOCKET,
+5 -67
View File
@@ -4,7 +4,7 @@ from trytond.protocols.sslsocket import SSLSocket
from trytond.protocols.dispatcher import dispatch
from trytond.config import CONFIG
from trytond.protocols.datatype import Float
from trytond.protocols.common import daemon
from trytond.protocols.common import daemon, GZipRequestHandlerMixin
from trytond import security
import SimpleXMLRPCServer
import SocketServer
@@ -13,8 +13,6 @@ import traceback
import socket
import sys
import os
import gzip
import StringIO
import base64
import datetime
from types import DictType
@@ -102,8 +100,10 @@ class GenericXMLRPCRequestHandler:
security.logout(database_name, user, session)
class SimpleXMLRPCRequestHandler(GenericXMLRPCRequestHandler,
class SimpleXMLRPCRequestHandler(GZipRequestHandlerMixin,
GenericXMLRPCRequestHandler,
SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
protocol_version = "HTTP/1.1"
rpc_paths = None
encode_threshold = 1400 # common MTU
@@ -127,69 +127,6 @@ class SimpleXMLRPCRequestHandler(GenericXMLRPCRequestHandler,
self.send_header("WWW-Authenticate", 'Basic realm="Tryton"')
return False
# Copy from SimpleXMLRPCServer.py with gzip encoding added
def do_POST(self):
"""Handles the HTTP POST request.
Attempts to interpret all HTTP POST requests as XML-RPC calls,
which are forwarded to the server's _dispatch method for handling.
"""
# Check that the path is legal
if not self.is_rpc_path_valid():
self.report_404()
return
try:
# Get arguments by reading body of request.
# We read this in chunks to avoid straining
# socket.read(); around the 10 or 15Mb mark, some platforms
# begin to have problems (bug #792570).
max_chunk_size = 10*1024*1024
size_remaining = int(self.headers["content-length"])
L = []
while size_remaining:
chunk_size = min(size_remaining, max_chunk_size)
L.append(self.rfile.read(chunk_size))
size_remaining -= len(L[-1])
data = ''.join(L)
# In previous versions of SimpleXMLRPCServer, _dispatch
# could be overridden in this class, instead of in
# SimpleXMLRPCDispatcher. To maintain backwards compatibility,
# check to see if a subclass implements _dispatch and dispatch
# using that method if present.
response = self.server._marshaled_dispatch(
data, getattr(self, '_dispatch', None)
)
except Exception: # This should only happen if the module is buggy
# internal error, report as HTTP server error
self.send_response(500)
self.end_headers()
else:
# got a valid XML RPC response
self.send_response(200)
self.send_header("Content-type", "text/xml")
# Handle gzip encoding
if 'gzip' in self.headers.get('Accept-Encoding', '').split(',') \
and len(response) > self.encode_threshold:
buffer = StringIO.StringIO()
output = gzip.GzipFile(mode='wb', fileobj=buffer)
output.write(response)
output.close()
buffer.seek(0)
response = buffer.getvalue()
self.send_header('Content-Encoding', 'gzip')
self.send_header("Content-length", str(len(response)))
self.end_headers()
self.wfile.write(response)
# shut down the connection
self.wfile.flush()
self.connection.shutdown(1)
class SecureXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
@@ -202,6 +139,7 @@ class SecureXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
class SimpleThreadedXMLRPCServer(SocketServer.ThreadingMixIn,
SimpleXMLRPCServer.SimpleXMLRPCServer):
timeout = 1
daemon_threads = True
def server_bind(self):
self.socket.setsockopt(socket.SOL_SOCKET,
-253
View File
@@ -1,253 +0,0 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
import socket
# can't use/fall-back pickle due to different interface :-(
import cPickle
try:
import cStringIO as StringIO
except ImportError:
import StringIO
try:
import ssl
except ImportError:
ssl = None
import gzip
try:
import hashlib
except ImportError:
hashlib = None
import sha
import os
DNS_CACHE = {}
MAX_SIZE = 999999999
MAX_LENGHT = len(str(MAX_SIZE))
CONNECT_TIMEOUT = 5
TIMEOUT = 3600
GZIP_THRESHOLD = 1400 # common MTU
_ALLOWED_MODULES = {'datetime': ['datetime', 'date'], 'decimal': ['Decimal']}
def checkfunction(module, klass):
if module in _ALLOWED_MODULES and klass in _ALLOWED_MODULES[module]:
mod = __import__(module, {}, {}, ['__all__'])
_class = getattr(mod, klass)
return _class
raise ValueError('Not supported: %s/%s' % (module, klass))
class PySocket:
def __init__(self, sock=None, fingerprints=None, ca_certs=None):
self.sock = sock
self.host = None
self.hostname = None
self.port = None
self.ssl = False
self.ssl_sock = None
self.connected = False
self.buffer = ''
self.fingerprints = fingerprints
if ca_certs and os.path.isfile(ca_certs):
self.ca_certs = ca_certs
else:
self.ca_certs = None
def connect(self, host, port=False):
if not port:
buf = host.split('//')[1]
host, port = buf.rsplit(':', 1)
hostname = host
if host in DNS_CACHE:
host = DNS_CACHE[host]
self.sock = None
if socket.has_ipv6:
try:
socket.getaddrinfo(host, int(port), socket.AF_INET6)
self.sock = socket.socket(socket.AF_INET6,
socket.SOCK_STREAM)
self.sock.settimeout(CONNECT_TIMEOUT)
self.sock.connect((host, int(port)))
except socket.error:
self.sock = None
if self.sock is None:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.settimeout(CONNECT_TIMEOUT)
self.sock.connect((host, int(port)))
DNS_CACHE[hostname], port = self.sock.getpeername()[:2]
try:
sock = None
if socket.has_ipv6:
try:
socket.getaddrinfo(host, int(port), socket.AF_INET6)
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
sock.settimeout(CONNECT_TIMEOUT)
sock.connect((host, int(port)))
except socket.error:
sock = None
if sock is None:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(CONNECT_TIMEOUT)
sock.connect((host, int(port)))
if ssl:
ssl_sock = ssl.wrap_socket(sock)
self.ssl = True
elif hasattr(socket, 'ssl'):
ssl_sock = socket.ssl(sock)
self.ssl = True
except socket.error:
pass
self.sock.settimeout(TIMEOUT)
fingerprint = None
if self.ssl:
if ssl:
self.ssl_sock = ssl.wrap_socket(self.sock,
ca_certs=self.ca_certs, cert_reqs=(self.ca_certs and
ssl.CERT_REQUIRED or ssl.CERT_NONE))
elif hasattr(socket, 'ssl'):
self.ssl_sock = socket.ssl(self.sock, certfile=self.ca_certs)
try:
peercert = self.ssl_sock.getpeercert(True)
except socket.error:
peercert = None
def format_hash(value):
return reduce(lambda x, y: x + y[1].upper() +
((y[0] % 2 and y[0] + 1 < len(value)) and ':' or ''),
enumerate(value), '')
if peercert and hashlib:
fingerprint = format_hash(hashlib.sha1(peercert).hexdigest())
elif peercert:
fingerprint = format_hash(sha1.new(peercert).hexdigest())
self.host = host
self.hostname = hostname
self.port = port
self.connected = True
self.buffer = ''
if self.fingerprints is not None:
key = (self.hostname, str(self.port))
if key in self.fingerprints:
if self.fingerprints[key] != fingerprint:
self.disconnect()
raise Exception('BadFingerprint')
elif fingerprint:
self.fingerprints[key] = fingerprint
def disconnect(self):
try:
sock = self.sock
if self.ssl:
sock = self.ssl_sock
try:
shutdown_value = 2
if hasattr(socket, 'SHUT_RDWR'):
shutdown_value = socket.SHUT_RDWR
if hasattr(sock, 'sock_shutdown'):
sock.sock_shutdown(shutdown_value)
else:
sock.shutdown(shutdown_value)
except socket.error:
pass
sock.close()
except socket.error:
pass
self.sock = None
self.ssl = False
self.ssl_sock = None
self.connected = False
self.buffer = ''
def reconnect(self):
if self.hostname and self.port:
self.disconnect()
self.connect(self.hostname, self.port)
def send(self, msg, exception=False, traceback=None):
msg = cPickle.dumps([msg, traceback], protocol=2)
gzip_p = False
if len(msg) > GZIP_THRESHOLD:
buffer = StringIO.StringIO()
output = gzip.GzipFile(mode='wb', fileobj=buffer)
output.write(msg)
output.close()
buffer.seek(0)
msg = buffer.getvalue()
gzip_p = True
size = len(msg)
msg = str(size) + ' ' + (exception and "1" or "0") \
+ (gzip_p and "1" or "0") + msg
size = len(msg)
if self.ssl:
totalsent = 0
while totalsent < size:
sent = self.ssl_sock.write(msg[totalsent:])
if sent == 0:
raise RuntimeError("socket connection broken")
totalsent = totalsent + sent
else:
self.sock.sendall(msg)
def receive(self):
buf = self.buffer
L = []
size_remaining = MAX_LENGHT
while size_remaining:
chunk_size = min(size_remaining, 4096)
if self.ssl:
chunk = self.ssl_sock.read(chunk_size)
else:
chunk = self.sock.recv(chunk_size)
if chunk == '':
raise RuntimeError("socket connection broken")
L.append(chunk)
size_remaining -= len(chunk)
if ' ' in chunk:
break
if size_remaining < 0:
raise RuntimeError("socket connection broken")
buf += ''.join(L)
size, msg = buf.split(' ', 1)
size = int(size)
if size > MAX_SIZE:
raise RuntimeError("socket connection broken")
while len(msg) < 2:
chunk_size = min(size + 2, 4096)
if self.ssl:
msg += self.ssl_sock.read(chunk_size)
else:
msg += self.sock.recv(chunk_size)
if msg == '':
raise RuntimeError("socket connection broken")
exception = msg[0] != "0"
gzip_p = msg[1] != "0"
L = [msg[2:]]
size_remaining = size - len(L[0])
while size_remaining:
chunk_size = min(size_remaining, 4096)
if self.ssl:
chunk = self.ssl_sock.read(chunk_size)
else:
chunk = self.sock.recv(chunk_size)
if chunk == '':
raise RuntimeError("socket connection broken")
L.append(chunk)
size_remaining -= len(chunk)
msg = ''.join(L)
if len(msg) > size:
self.buffer = msg[size:]
msg = msg[:size]
else:
self.buffer = ''
msgio = StringIO.StringIO(msg)
if gzip_p:
output = gzip.GzipFile(mode='r', fileobj=msgio)
msgio = StringIO.StringIO(output.read(-1))
output.close()
unpickler = cPickle.Unpickler(msgio)
# cPickle mechanism to import instances (pickle differs here)
unpickler.find_global = checkfunction
res = unpickler.load()
if exception:
raise Exception(*(list(res[0]) + [res[1]]))
else:
return res[0]
-13
View File
@@ -170,14 +170,6 @@ class TrytonServer(object):
(CONFIG['secure_jsonrpc'] and ' Secure' or '',
CONFIG['jsonport']))
if CONFIG['netrpc']:
from trytond.protocols.netrpc import NetRPCServerThread
netrpcd = NetRPCServerThread(CONFIG['interface'], CONFIG['netport'],
CONFIG['secure_netrpc'])
self.logger.info("starting NetRPC%s protocol, port %d" % \
(CONFIG['secure_netrpc'] and ' Secure' or '',
CONFIG['netport']))
if CONFIG['webdav']:
from trytond.protocols.webdav import WebDAVServerThread
webdavd = WebDAVServerThread(CONFIG['interface'],
@@ -191,9 +183,6 @@ class TrytonServer(object):
if signum == signal.SIGUSR1:
Pool.start()
return
if CONFIG['netrpc']:
netrpcd.stop()
netrpcd.join()
if CONFIG['xmlrpc']:
xmlrpcd.stop()
xmlrpcd.join()
@@ -221,8 +210,6 @@ class TrytonServer(object):
signal.signal(signal.SIGUSR1, handler)
self.logger.info('waiting for connections...')
if CONFIG['netrpc']:
netrpcd.start()
if CONFIG['xmlrpc']:
xmlrpcd.start()
if CONFIG['jsonrpc']: