add simple Ruby HTTP server and client classes
Using Mongrel for the server.
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@668894 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/rb/lib/thrift/server/thttpserver.rb b/lib/rb/lib/thrift/server/thttpserver.rb
new file mode 100644
index 0000000..7dce218
--- /dev/null
+++ b/lib/rb/lib/thrift/server/thttpserver.rb
@@ -0,0 +1,43 @@
+#!/usr/bin/env ruby
+
+require 'thrift/protocol/tprotocol'
+require 'thrift/protocol/tbinaryprotocol'
+require 'thrift/transport/ttransport'
+
+require 'mongrel'
+
+## Sticks a service on a URL, using mongrel to do the HTTP work
+class TSimpleMongrelHTTPServer
+ class Handler < Mongrel::HttpHandler
+ def initialize processor, protocol_factory
+ @processor = processor
+ @protocol_factory = protocol_factory
+ end
+
+ def process request, response
+ unless request.params["REQUEST_METHOD"] == "POST"
+ response.start(404) { } # better way?
+ return
+ end
+ response.start(200) do |head, out|
+ head["Content-Type"] = "application/x-thrift"
+ transport = TIOStreamTransport.new request.body, out
+ protocol = @protocol_factory.getProtocol transport
+ @processor.process protocol, protocol
+ end
+ end
+ end
+
+ def initialize processor, opts={}
+ port = opts[:port] || 80
+ ip = opts[:ip] || "0.0.0.0"
+ path = opts[:path] || ""
+ protocol_factory = opts[:protocol_factory] || TBinaryProtocolFactory.new
+ @server = Mongrel::HttpServer.new ip, port
+ @server.register "/#{path}", Handler.new(processor, protocol_factory)
+ end
+
+ def serve
+ @server.run.join
+ end
+end
diff --git a/lib/rb/lib/thrift/transport/thttpclient.rb b/lib/rb/lib/thrift/transport/thttpclient.rb
new file mode 100644
index 0000000..a3f391f
--- /dev/null
+++ b/lib/rb/lib/thrift/transport/thttpclient.rb
@@ -0,0 +1,25 @@
+#!/usr/bin/env ruby
+
+require 'thrift/transport/ttransport'
+
+require 'net/http'
+require 'uri'
+require 'stringio'
+
+## Very simple HTTP client
+class THttpClient < TTransport
+ def initialize url
+ @url = URI url
+ @outbuf = ""
+ end
+
+ def isOpen; true end
+ def read sz; @inbuf.read sz end
+ def write buf; @outbuf << buf end
+ def flush
+ http = Net::HTTP.new @url.host, @url.port
+ resp, data = http.post(@url.path, @outbuf)
+ @inbuf = StringIO.new data
+ @outbuf = ""
+ end
+end
diff --git a/lib/rb/lib/thrift/transport/ttransport.rb b/lib/rb/lib/thrift/transport/ttransport.rb
index a9ea5e5..e2a55d5 100644
--- a/lib/rb/lib/thrift/transport/ttransport.rb
+++ b/lib/rb/lib/thrift/transport/ttransport.rb
@@ -269,3 +269,18 @@
def flush
end
end
+
+## Very very simple implementation of wrapping two objects, one with a #read
+## method and one with a #write method, into a transport for thrift.
+##
+## Assumes both objects are open, remain open, don't require flushing, etc.
+class TIOStreamTransport < TTransport
+ def initialize input, output
+ @input = input
+ @output = output
+ end
+
+ def isOpen(); true end
+ def read(sz); @input.read(sz) end
+ def write(buf); @output.write(buf) end
+end