diff options
author | Kristján Valur Jónsson <kristjan@ccpgames.com> | 2009-06-28 21:04:17 (GMT) |
---|---|---|
committer | Kristján Valur Jónsson <kristjan@ccpgames.com> | 2009-06-28 21:04:17 (GMT) |
commit | e007860b8b3609ce0bc62b1780efaa06241520bd (patch) | |
tree | 687961d29bff1d936ed949cf591bbe8285d9e54d /Lib/SimpleXMLRPCServer.py | |
parent | 552e7a7e2f526fa0637a3e14f47354c567dfe26e (diff) | |
download | cpython-e007860b8b3609ce0bc62b1780efaa06241520bd.zip cpython-e007860b8b3609ce0bc62b1780efaa06241520bd.tar.gz cpython-e007860b8b3609ce0bc62b1780efaa06241520bd.tar.bz2 |
http://bugs.python.org/issue6267
Cumulative patch to http and xmlrpc
Diffstat (limited to 'Lib/SimpleXMLRPCServer.py')
-rw-r--r-- | Lib/SimpleXMLRPCServer.py | 57 |
1 files changed, 51 insertions, 6 deletions
diff --git a/Lib/SimpleXMLRPCServer.py b/Lib/SimpleXMLRPCServer.py index 967ac7e..5b5aced 100644 --- a/Lib/SimpleXMLRPCServer.py +++ b/Lib/SimpleXMLRPCServer.py @@ -106,6 +106,7 @@ import BaseHTTPServer import sys import os import traceback +import re try: import fcntl except ImportError: @@ -430,6 +431,31 @@ class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): # paths not on this list will result in a 404 error. rpc_paths = ('/', '/RPC2') + #if not None, encode responses larger than this, if possible + encode_threshold = 1400 #a common MTU + + #Override form StreamRequestHandler: full buffering of output + #and no Nagle. + wbufsize = -1 + disable_nagle_algorithm = True + + # a re to match a gzip Accept-Encoding + aepattern = re.compile(r""" + \s* ([^\s;]+) \s* #content-coding + (;\s* q \s*=\s* ([0-9\.]+))? #q + """, re.VERBOSE | re.IGNORECASE) + + def accept_encodings(self): + r = {} + ae = self.headers.get("Accept-Encoding", "") + for e in ae.split(","): + match = self.aepattern.match(e) + if match: + v = match.group(3) + v = float(v) if v else 1.0 + r[match.group(1)] = v + return r + def is_rpc_path_valid(self): if self.rpc_paths: return self.path in self.rpc_paths @@ -463,6 +489,10 @@ class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): 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, @@ -481,18 +511,36 @@ class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): self.send_header("X-exception", str(e)) self.send_header("X-traceback", traceback.format_exc()) + self.send_header("Content-length", "0") self.end_headers() else: # got a valid XML RPC response self.send_response(200) self.send_header("Content-type", "text/xml") + if self.encode_threshold is not None: + if len(response) > self.encode_threshold: + q = self.accept_encodings().get("gzip", 0) + if q: + response = xmlrpclib.gzip_encode(response) + 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 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": + try: + return xmlrpclib.gzip_decode(data) + except ValueError: + self.send_response(400, "error decoding gzip content") + else: + self.send_response(501, "encoding %r not supported" % encoding) + self.send_header("Content-length", "0") + self.end_headers() def report_404 (self): # Report a 404 error @@ -502,9 +550,6 @@ class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): 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 log_request(self, code='-', size='-'): """Selectively log an accepted request.""" |