From f78ec2bc66d3a9fcfd63b9bdf49fc9bdc68b4cf7 Mon Sep 17 00:00:00 2001 From: David Reiss Date: Sat, 31 Jan 2009 21:59:32 +0000 Subject: [PATCH] THRIFT-195. python: Add a simple THttpServer git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@739638 13f79535-47bb-0310-9956-ffa450edef68 --- lib/py/src/server/THttpServer.py | 50 ++++++++++++++++++++++++++++++++ test/py/RunClientServer.py | 12 ++++++-- test/py/TestClient.py | 21 +++++++++----- test/py/TestServer.py | 21 +++++++++----- 4 files changed, 87 insertions(+), 17 deletions(-) create mode 100644 lib/py/src/server/THttpServer.py diff --git a/lib/py/src/server/THttpServer.py b/lib/py/src/server/THttpServer.py new file mode 100644 index 00000000..7a75619f --- /dev/null +++ b/lib/py/src/server/THttpServer.py @@ -0,0 +1,50 @@ +# Copyright (c) 2006- Facebook +# Distributed under the Thrift Software License +# +# See accompanying file LICENSE or visit the Thrift site at: +# http://developers.facebook.com/thrift/ + +import BaseHTTPServer + +from thrift.server import TServer +from thrift.transport import TTransport + +class THttpServer(TServer.TServer): + """A simple HTTP-based Thrift server + + This class is not very performant, but it is useful (for example) for + acting as a mock version of an Apache-based PHP Thrift endpoint.""" + + def __init__(self, processor, server_address, + inputProtocolFactory, outputProtocolFactory = None): + """Set up protocol factories and HTTP server. + + See BaseHTTPServer for server_address. + See TServer for protocol factories.""" + + if outputProtocolFactory is None: + outputProtocolFactory = inputProtocolFactory + + TServer.TServer.__init__(self, processor, None, None, None, + inputProtocolFactory, outputProtocolFactory) + + thttpserver = self + + class RequestHander(BaseHTTPServer.BaseHTTPRequestHandler): + def do_POST(self): + # Don't care about the request path. + self.send_response(200) + self.send_header("content-type", "application/x-thrift") + self.end_headers() + + itrans = TTransport.TFileObjectTransport(self.rfile) + otrans = TTransport.TFileObjectTransport(self.wfile) + iprot = thttpserver.inputProtocolFactory.getProtocol(itrans) + oprot = thttpserver.outputProtocolFactory.getProtocol(otrans) + thttpserver.processor.process(iprot, oprot) + otrans.flush() + + self.httpd = BaseHTTPServer.HTTPServer(server_address, RequestHander) + + def serve(self): + self.httpd.serve_forever() diff --git a/test/py/RunClientServer.py b/test/py/RunClientServer.py index b4fd3826..34f883ec 100755 --- a/test/py/RunClientServer.py +++ b/test/py/RunClientServer.py @@ -19,6 +19,8 @@ def runTest(server_class): argv = [sys.executable, relfile("TestClient.py")] if server_class in FRAMED: argv.append('--framed') + if server_class == 'THttpServer': + argv.append('--http=/') ret = subprocess.call(argv) if ret != 0: raise Exception("subprocess failed") @@ -29,5 +31,11 @@ def runTest(server_class): # wait for shutdown time.sleep(1) -map(runTest, ["TForkingServer", "TThreadPoolServer", - "TThreadedServer", "TSimpleServer", "TNonblockingServer"]) +map(runTest, [ + "TSimpleServer", + "TThreadedServer", + "TThreadPoolServer", + "TForkingServer", + "TNonblockingServer", + "THttpServer", + ]) diff --git a/test/py/TestClient.py b/test/py/TestClient.py index 501d197d..944e3846 100755 --- a/test/py/TestClient.py +++ b/test/py/TestClient.py @@ -8,6 +8,7 @@ from ThriftTest import ThriftTest from ThriftTest.ttypes import * from thrift.transport import TTransport from thrift.transport import TSocket +from thrift.transport import THttpClient from thrift.protocol import TBinaryProtocol import unittest import time @@ -15,13 +16,15 @@ from optparse import OptionParser parser = OptionParser() -parser.set_defaults(framed=False, verbose=1, host='localhost', port=9090) +parser.set_defaults(framed=False, http_path=None, verbose=1, host='localhost', port=9090) parser.add_option("--port", type="int", dest="port", help="connect to server at port") parser.add_option("--host", type="string", dest="host", help="connect to server") parser.add_option("--framed", action="store_true", dest="framed", help="use framed transport") +parser.add_option("--http", dest="http_path", + help="Use the HTTP transport with the specified path") parser.add_option('-v', '--verbose', action="store_const", dest="verbose", const=2, help="verbose output") @@ -33,13 +36,17 @@ options, args = parser.parse_args() class AbstractTest(unittest.TestCase): def setUp(self): - socket = TSocket.TSocket(options.host, options.port) - - # Frame or buffer depending upon args - if options.framed: - self.transport = TTransport.TFramedTransport(socket) + if options.http_path: + self.transport = THttpClient.THttpClient( + options.host, options.port, options.http_path) else: - self.transport = TTransport.TBufferedTransport(socket) + socket = TSocket.TSocket(options.host, options.port) + + # frame or buffer depending upon args + if options.framed: + self.transport = TTransport.TFramedTransport(socket) + else: + self.transport = TTransport.TBufferedTransport(socket) self.transport.open() diff --git a/test/py/TestServer.py b/test/py/TestServer.py index a7bf6d06..7abb624d 100755 --- a/test/py/TestServer.py +++ b/test/py/TestServer.py @@ -9,7 +9,7 @@ from ThriftTest.ttypes import * from thrift.transport import TTransport from thrift.transport import TSocket from thrift.protocol import TBinaryProtocol -from thrift.server import TServer, TNonblockingServer +from thrift.server import TServer, TNonblockingServer, THttpServer class TestHandler: @@ -77,15 +77,20 @@ class TestHandler: def testTypedef(self, thing): return thing +pfactory = TBinaryProtocol.TBinaryProtocolFactory() handler = TestHandler() processor = ThriftTest.Processor(handler) -transport = TSocket.TServerSocket(9090) -tfactory = TTransport.TBufferedTransportFactory() -pfactory = TBinaryProtocol.TBinaryProtocolFactory() -if sys.argv[1] == "TNonblockingServer": - server = TNonblockingServer.TNonblockingServer(processor, transport) +if sys.argv[1] == "THttpServer": + server = THttpServer.THttpServer(processor, ('', 9090), pfactory) else: - ServerClass = getattr(TServer, sys.argv[1]) - server = ServerClass(processor, transport, tfactory, pfactory) + transport = TSocket.TServerSocket(9090) + tfactory = TTransport.TBufferedTransportFactory() + + if sys.argv[1] == "TNonblockingServer": + server = TNonblockingServer.TNonblockingServer(processor, transport) + else: + ServerClass = getattr(TServer, sys.argv[1]) + server = ServerClass(processor, transport, tfactory, pfactory) + server.serve() -- 2.17.1