Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ a string (`name`) and enum (`favoriteWord`):
"service": "ExampleService",
"function": "greet",
"protocol": "Thrift::CompactProtocol",
"transport": "Thrift::FramedTransport",
"socket": "Thrift::Socket",
"host": "localhost",
"port": "9000",
"args": {
Expand Down
2 changes: 2 additions & 0 deletions lib/scrimp.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# coding: UTF-8

require 'thrift'
require 'scrimp/ssl_socket'
require 'scrimp/ssl_server_socket'
require 'scrimp/version'
require 'scrimp/json_thrift'
require 'scrimp/thrift_util'
Expand Down
21 changes: 18 additions & 3 deletions lib/scrimp/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
module Scrimp
class App < Sinatra::Base
set :static, true
set :public, File.expand_path('../public', __FILE__)
set :public_folder, File.expand_path('../public', __FILE__)
set :views, File.expand_path('../views', __FILE__)
set :haml, :format => :html5

Expand Down Expand Up @@ -55,6 +55,20 @@ class App < Sinatra::Base
protocols.to_json
end

get '/transports' do
transports = {'Thrift::FramedTransport'=>'Thrift::FramedTransport',
'Thrift::BufferedTransport'=>'Thrift::BufferedTransport'}
content_type :json
transports.to_json
end

get '/sockets' do
sockets = {'Thrift::Socket'=>'Thrift::Socket',
'Thrift::SSLSocket'=>'Thrift::SSLSocket'}
content_type :json
sockets.to_json
end

get '/structs' do
structs = {}
ThriftUtil.all_structs.each do |struct|
Expand Down Expand Up @@ -88,8 +102,9 @@ class App < Sinatra::Base
end.compact

begin
transport = Thrift::FramedTransport.new Thrift::Socket.new(invocation['host'], invocation['port'])
protocol_class = ThriftUtil.qualified_const invocation['protocol']
socket = Object::const_get(invocation['socket']||'Thrift::Socket').new(invocation['host'], invocation['port'])
transport = Object::const_get(invocation['transport']||'Thrift::FramedTransport').new(socket)
protocol_class = ThriftUtil.qualified_const invocation['protocol']||'Thrift::CompactProtocol'
protocol = protocol_class.new transport
client = service_class.const_get('Client').new protocol
transport.open
Expand Down
30 changes: 28 additions & 2 deletions lib/scrimp/public/main.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ default_request = ->
request =
service: (service for service of Scrimp.services)[0]
protocol: (protocol for protocol of Scrimp.protocols)[0]
transport: (transport for transport of Scrimp.transports)[0]
socket: (socket for socket of Scrimp.sockets)[0]
host: "localhost"
port: 9000
args: {}
Expand All @@ -22,8 +24,20 @@ load_structs = (data) ->
load_protocols = (data) ->
Scrimp.protocols = data
for protocol of Scrimp.protocols
option = $('<option>').val(protocol).text(protocol)
$('select.protocol-field').append(option)
option = $('<option>').val(protocol).text(protocol)
$('select.protocol-field').append(option)

load_transports = (data) ->
Scrimp.transports = data
for transport of Scrimp.transports
option = $('<option>').val(transport).text(transport)
$('select.transport-field').append(option)

load_sockets = (data) ->
Scrimp.sockets = data
for socket of Scrimp.sockets
option = $('<option>').val(socket).text(socket)
$('select.socket-field').append(option)

service_changed = ->
$('select.function-field').empty()
Expand Down Expand Up @@ -150,6 +164,8 @@ load_structured_request = ->
$('select.function-field').val(parsed.function)
function_changed()
$('select.protocol-field').val(parsed.protocol)
$('select.socket-field').val(parsed.socket)
$('select.transport-field').val(parsed.transport)
$('input.host-field').val(parsed.host)
$('input.port-field').val(parsed.port)
true
Expand Down Expand Up @@ -189,6 +205,8 @@ build_raw_request = ->
service: $('select.service-field').val()
function: $('select.function-field').val()
protocol: $('select.protocol-field').val()
transport: $('select.transport-field').val()
socket: $('select.socket-field').val()
host: $('input.host-field').val()
port: $('input.port-field').val()
args: build_json_for_field($('.args-field'))
Expand Down Expand Up @@ -280,6 +298,14 @@ $ ->
success: load_protocols
url: '/protocols'
async: false
$.ajax
success: load_transports
url: '/transports'
async: false
$.ajax
success: load_sockets
url: '/sockets'
async: false
$('select.service-field').change(service_changed)
$('select.function-field').change(function_changed)
$('.request-json').val(JSON.stringify(default_request(), null, 2))
Expand Down
48 changes: 48 additions & 0 deletions lib/scrimp/ssl_server_socket.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# encoding: ascii-8bit
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#

require 'socket'
require 'openssl'

module Thrift
class SSLServerSocket < ServerSocket
# call-seq: initialize(host = nil, port)
def initialize(host_or_port, port = nil, key, cert)
super(host_or_port, port)

@ssl_context = OpenSSL::SSL::SSLContext.new()
@ssl_context.cert = OpenSSL::X509::Certificate.new(File.open(cert))
@ssl_context.key = OpenSSL::PKey::RSA.new(File.open(key))
end

def listen
socket = TCPServer.new(@host, @port)
@handle = OpenSSL::SSL::SSLServer.new(socket, @ssl_context)
end

def accept
begin
super
rescue OpenSSL::SSL::SSLError
retry
end
end
end
end
53 changes: 53 additions & 0 deletions lib/scrimp/ssl_socket.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# encoding: ascii-8bit
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#

require 'socket'
require 'openssl'

module Thrift
class SSLSocket < Socket
def initialize(host='localhost', port=9090, timeout=nil, ca=nil)
super(host, port, timeout)

@ssl_context = OpenSSL::SSL::SSLContext.new()

if ca != nil
@ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
@ssl_context.ca_file = ca
end
end

def open
socket = super
@handle = OpenSSL::SSL::SSLSocket.new(socket, @ssl_context)
begin
@handle.connect_nonblock
rescue IO::WaitReadable
IO.select([ @handle ], nil, nil, @timeout)
retry
rescue IO::WaitWritable
IO.select(nil, [ @handle ], nil, @timeout)
retry
end

@handle
end
end
end
6 changes: 6 additions & 0 deletions lib/scrimp/views/index.haml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@
.field
%label.protocol-field{:name => 'protocol'} Protocol
%select.protocol-field{:name => 'protocol'}
.field
%label.transport-field{:name => 'transport'} Transport
%select.transport-field{:name => 'transport'}
.field
%label.socket-field{:name => 'socket'} Socket
%select.socket-field{:name => 'socket'}
.field
%label.host-field{:name => 'host'} Host
%input.host-field{:name => 'host', :type => 'text'}
Expand Down
51 changes: 42 additions & 9 deletions sample/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,46 @@

require 'optparse'
require 'tmpdir'
require 'scrimp'

options = {port: 9000,
thrift_command: 'thrift'}
options = {host: 'localhost',
port: 9000,
thrift_command: 'thrift',
protocol: 'Thrift::CompactProtocolFactory',
transport: 'Thrift::FramedTransportFactory',
socket: 'Thrift::ServerSocket',
server: 'Thrift::SimpleServer',
cert: 'sample/testing_hosting.pem',
key: 'sample/testing_hosting.key'
}
parser = OptionParser.new do |op|
op.on '--host HOST', 'host to launch Thrift server on' do |host|
options[:host] = host
end
op.on '-p', '--port PORT', 'port to launch Thrift server on' do |port|
options[:port] = port.to_i
end
op.on '-t', '--thrift-command COMMAND', 'thrift compiler' do |cmd|
options[:thrift_command] = cmd
end
op.on '--protocol PROTOCOL', 'protocol ( Thrift::CompactProtocolFactory, Thrift::BinaryProtocolFactory )' do |proto|
options[:protocol] = proto
end
op.on '--transport TRANSPORT', 'transport ( Thrift::BufferedTransportFactory, Thrift::FramedTransportFactory )' do |trans|
options[:transport] = trans
end
op.on '--socket SOCKET', 'socket ( Thrift::ServerSocket Thrift::SSLServerSocket )' do |sock|
options[:socket] = sock
end
op.on '--server SERVER', 'server ( Thrift::SimpleServer )' do |serv|
options[:server] = serv
end
op.on '--cert CERT', 'cert ( hosting.pem )' do |cert|
options[:cert] = cert
end
op.on '--key KEY', 'key ( hosting.key )' do |key|
options[:key] = key
end
op.on '-h', '--help' do
puts parser
exit 0
Expand All @@ -27,10 +57,10 @@

Dir.mktmpdir do |out|
path = File.expand_path(File.join(File.dirname(__FILE__), 'example.thrift'))
puts (cmd = "#{options[:thrift_command]} --gen rb --out #{out} #{path}")
puts (cmd = "#{options[:thrift_command]} --gen rb:namespaced --out #{out} #{path}")
puts `#{cmd}`
$LOAD_PATH.unshift out
Dir["#{out}/*.rb"].each {|file| require file}
Dir["#{out}/**/*.rb"].each {|file| require file}
$LOAD_PATH.delete out
end

Expand Down Expand Up @@ -76,10 +106,13 @@ def onewayMethod(message)
end

processor = ExampleServiceImpl::Processor.new(ExampleServiceImpl.new)
transport = Thrift::ServerSocket.new('localhost', options[:port])
transport_factory = Thrift::FramedTransportFactory.new
protocol_factory = Thrift::CompactProtocolFactory.new
server = Thrift::SimpleServer.new(processor, transport, transport_factory, protocol_factory)

puts "Starting example service for localhost on port #{options[:port]}"
# Here's the dynamic part
socket_args = options[:socket] == "Thrift::SSLServerSocket" ? [options[:host], options[:port], options[:key] ,options[:cert]] : [options[:host], options[:port]]
socket = Object::const_get(options[:socket]).new(*socket_args)
transport = Object::const_get(options[:transport]).new
protocol = Object::const_get(options[:protocol]).new
server = Object::const_get(options[:server]).new(processor, socket, transport, protocol)

puts "Starting example service as #{options[:server]} #{options[:socket]} #{options[:transport]} #{options[:protocol]} for #{options[:host]} on port #{options[:port]}"
server.serve
54 changes: 54 additions & 0 deletions sample/testing.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,2956F7ABB96A99042F65FDAE24F89FE1

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
-----END RSA PRIVATE KEY-----
Loading