Skip to content
This repository has been archived by the owner on Dec 7, 2018. It is now read-only.

Commit

Permalink
Merge pull request #68 from celluloid/ssl
Browse files Browse the repository at this point in the history
SSL support
  • Loading branch information
tarcieri committed Jun 25, 2013
2 parents 77b6453 + 817cbe7 commit 6732f22
Show file tree
Hide file tree
Showing 13 changed files with 262 additions and 9 deletions.
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ gem 'coveralls', require: false
# Specify your gem's dependencies in reel.gemspec
gemspec

group :development do
gem 'guard-rspec'
gem 'pry'
end
24 changes: 24 additions & 0 deletions Guardfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# A sample Guardfile
# More info at https://github.com/guard/guard#readme

guard :rspec do
watch(%r{^spec/.+_spec\.rb$})
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
watch('spec/spec_helper.rb') { "spec" }

# Rails example
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
watch('config/routes.rb') { "spec/routing" }
watch('app/controllers/application_controller.rb') { "spec/controllers" }

# Capybara features specs
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" }

# Turnip features and steps
watch(%r{^spec/acceptance/(.+)\.feature$})
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
end

27 changes: 27 additions & 0 deletions examples/ssl_hello_world.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env ruby
# Run with: bundle exec examples/hello_world.rb

require 'rubygems'
require 'bundler/setup'
require 'reel'

addr, port = '127.0.0.1', 4430
options = {
:cert => File.read(File.expand_path("../../spec/fixtures/server.crt", __FILE__)),
:key => File.read(File.expand_path("../../spec/fixtures/server.key", __FILE__))
}

puts "*** Starting server on #{addr}:#{port}"
Reel::SSLServer.supervise(addr, port, options) do |connection|
# To use keep-alive with Reel, use a while loop that repeatedly calls
# connection.request and consumes connection objects
while request = connection.request
# Ordinarily we'd route the request here, e.g.
# route request.url
connection.respond :ok, "hello, world!"
end

# Reel takes care of closing the connection
end

sleep
1 change: 1 addition & 0 deletions lib/reel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
require 'reel/request_parser'
require 'reel/response'
require 'reel/server'
require 'reel/ssl_server'
require 'reel/websocket'
require 'reel/stream'

Expand Down
11 changes: 5 additions & 6 deletions lib/reel/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ class Server
# How many connections to backlog in the TCP accept queue
DEFAULT_BACKLOG = 100

# FIXME: remove respond_to? check after Celluloid 1.0
finalizer :finalize if respond_to?(:finalizer)
execute_block_on_receiver :initialize
finalizer :shutdown

def initialize(host, port, backlog = DEFAULT_BACKLOG, &callback)
# This is actually an evented Celluloid::IO::TCPServer
Expand All @@ -16,9 +16,7 @@ def initialize(host, port, backlog = DEFAULT_BACKLOG, &callback)
async.run
end

execute_block_on_receiver :initialize

def finalize
def shutdown
@server.close if @server
end

Expand All @@ -28,8 +26,9 @@ def run

def handle_connection(socket)
connection = Connection.new(socket)

begin
@callback[connection]
@callback.call(connection)
ensure
if connection.attached?
connection.close rescue nil
Expand Down
39 changes: 39 additions & 0 deletions lib/reel/ssl_server.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module Reel
class SSLServer < Server
execute_block_on_receiver :initialize

def initialize(host, port, options = {}, &callback)
backlog = options.fetch(:backlog, DEFAULT_BACKLOG)

# Ideally we can encapsulate this rather than making Ruby OpenSSL a
# mandatory part of the Reel API. It would be nice to support
# alternatives (e.g. Puma's MiniSSL)
ssl_context = OpenSSL::SSL::SSLContext.new
ssl_context.cert = OpenSSL::X509::Certificate.new options.fetch(:cert)
ssl_context.key = OpenSSL::PKey::RSA.new options.fetch(:key)

# FIXME: VERY VERY VERY VERY BAD RELEASE BLOCKER BAD
ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE

@tcpserver = Celluloid::IO::TCPServer.new(host, port)
@server = Celluloid::IO::SSLServer.new(@tcpserver, ssl_context)
@server.listen(backlog)
@callback = callback

async.run
end

def run
loop do
begin
socket = @server.accept
rescue OpenSSL::SSL::SSLError
# TODO: log this?
retry
end

async.handle_connection socket
end
end
end
end
3 changes: 2 additions & 1 deletion reel.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ Gem::Specification.new do |gem|
gem.require_paths = ["lib"]
gem.version = Reel::VERSION

gem.add_runtime_dependency 'celluloid-io', '>= 0.8.0'
gem.add_runtime_dependency 'celluloid', '>= 0.14.1'
gem.add_runtime_dependency 'celluloid-io', '>= 0.14.1'
gem.add_runtime_dependency 'http', '>= 0.2.0'
gem.add_runtime_dependency 'http_parser.rb', '>= 0.6.0.beta.2'
gem.add_runtime_dependency 'websocket_parser', '>= 0.1.4'
Expand Down
22 changes: 22 additions & 0 deletions spec/fixtures/client.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDmjCCAoICCQDwZ8yE/0n4PjANBgkqhkiG9w0BAQUFADCBjjELMAkGA1UEBhMC
VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28x
EjAQBgNVBAoTCUNlbGx1bG9pZDEbMBkGA1UEAxMSY2xpZW50LmV4YW1wbGUuY29t
MSEwHwYJKoZIhvcNAQkBFhJjbGllbnRAZXhhbXBsZS5jb20wHhcNMTIxMTI1MTkx
NjI2WhcNMjIxMTIzMTkxNjI2WjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNh
bGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEjAQBgNVBAoTCUNlbGx1
bG9pZDEbMBkGA1UEAxMSY2xpZW50LmV4YW1wbGUuY29tMSEwHwYJKoZIhvcNAQkB
FhJjbGllbnRAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQDV6zzpkAIX4FijnytX84GgHb8hYdNJAn+9g57XGrqtAH6BlLoANFl4n/+y
nEQwBqlrNnfstPrf7sPezytntSVyufSE+LGUGBJA/jyjQCMcEe8+4bfOC2ZhCpvn
I2dKNKwsmM+DyWs/PVl7XEAZF2P4iQ8eGLVFjph+KA/D79cHkIeGt4FEA4xJWqKf
+Kjftxo1cBqLx2dUiucRL7tva3ingAqYSs/i82jKLGlj7fdRMytOx87Nhs35RWpu
66l7hvpetx3t2wU2obKOzKhS4ycaZ2AptEDNXKaBTQ5lejSRxFBCpYQtqmkd0bMG
/T5ZfXC45axj9a2rj8AKZct+mLCzAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAHzr
b4VTktAi+8baGRJCXupt0Ari8ffoWhsYerELFLQF7K2sluxOqCsGEEF21e99fZxP
lisLi0DIQ7cNlOGjRJ3xaydE74Fsry3xBNKoR8I7OMr9VFsrC54tc0x7NQ7bRHy6
kCjSwKN4I2KWJjQ8yf8mIalmUKOmb/hirzna8io4CiDeJGZ1XNAQ9dl1RHRW442G
GTu2ofAtU8TlzilZyclMY/lN7whw7sKP+pPr6fpAOJZsR64IzbBcWHHjJhx70XOx
jnd5FB1oXnuupgPqEKmatSCytrue8GTkanB8VZ6+Zd/4XgTkie3UtCZW8R+NL/Lo
us/+Ks3WIDyYdPSPnbE=
-----END CERTIFICATE-----
27 changes: 27 additions & 0 deletions spec/fixtures/client.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA1es86ZACF+BYo58rV/OBoB2/IWHTSQJ/vYOe1xq6rQB+gZS6
ADRZeJ//spxEMAapazZ37LT63+7D3s8rZ7Ulcrn0hPixlBgSQP48o0AjHBHvPuG3
zgtmYQqb5yNnSjSsLJjPg8lrPz1Ze1xAGRdj+IkPHhi1RY6YfigPw+/XB5CHhreB
RAOMSVqin/io37caNXAai8dnVIrnES+7b2t4p4AKmErP4vNoyixpY+33UTMrTsfO
zYbN+UVqbuupe4b6Xrcd7dsFNqGyjsyoUuMnGmdgKbRAzVymgU0OZXo0kcRQQqWE
LappHdGzBv0+WX1wuOWsY/Wtq4/ACmXLfpiwswIDAQABAoIBAQCFDDcpaUj0ArP+
qEuz+x6/MGEk6QwZV7WNcGSFkvlSCoGkJJV+9RBExvao5yo92JbcuNbj4Tg7uOwY
EzAC45a0AVZEscz4t/P6emXKf2SW28y6hnbkbxCxAIEwxENE0vfXEP/YDplmjsit
whWXxYWHGe/OHz33UhYkONR9YBmUeLrtloRNUV82XDSpn4d7toLKaZW2kOFl4nFR
SQ3pDPk1hleG8AZcfnF2LwaPx1XjPwBnXY9FK2jyNupVghfCw/Sv91dbbVkkIG14
A8WpZKAXjXXOcTroof5+NJSPXzYrRuvP8K6H2zGj7F/AsP4hiZqGkb4tel0yH5VM
oLCUTHqhAoGBAPysxeoT1ytajQ55UV1yjsnQ3jF9YcWsZwPEJgMI+bt+QzAfqqZs
Kuvg8Gi7ukbcc2pKwXv+ma9HLJq/pQbWlfxcMNulY0VCPY/ceaPen+EfCJTApVpY
YFS25i/JnIp9IudpQBuLHz9Yy4f1W2VoeG/mFqOmUxiTx4LM87G6rdtDAoGBANi7
5raiwDS+rD91l5FLq3kdvgSDgYk4hh7BBJNJt8vhJYInIev5eb/Z41X8PfqWa2ir
9aanpMYhWDJxbdSQDd3/op6jtOZM7InLceAm2O29VY2+HW5ePpc21AHsqoZpFYEZ
YP8xvbSjJzfkrYr4y+aAMXONVAi4afqG7x6GqCXRAoGBAPbzFWu1gHKKyZn/0Bn4
wL1WOhM8a7Z6zSPNLSmCODGbMadzC6Ijzb9D1TNHZsOi6dpUvc2mBCZe9aU48N1C
FMzUfZvuhJtIJkrYPLp/9tpbLlPUBMfL4Dprl4XVEf34V4i8QT+qNRwAeMukbXMr
K6qRwkanZEd9B107WmG2Bf1pAoGACpld1g6tgabVe6D/kY52y0yGD2hy/Ef0Xyqn
U6CmSWUwVWYehZDEwHoiYQEd8tRKWmsWb1kBeOMGkijz6xJEa1fmFwYAgca/RpnZ
btHXiADbXzwt6kjXnMOEqLdvO3WGJLMeCDzhfyT/dP9M8V/rcNFSGcmOk4KZRDQ3
G3IQZRECgYBqHqvxHeL087UHXE1tdAGFVfxOiYE1afksJbkV06VnO8XXr9sNSWwy
YjXVY9k6U1BFo7jHrWr6TkeMkB45wyn/fasHKU7qsPt0joRFkXMCzwl376hto3Tg
RGXQCA4RUQXkxaDctJ5TgcF7MhK7tAFd1aBVlxwGENLYUVL0ZPaMrw==
-----END RSA PRIVATE KEY-----
22 changes: 22 additions & 0 deletions spec/fixtures/server.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDmjCCAoICCQD+dJ16wNIKnzANBgkqhkiG9w0BAQUFADCBjjELMAkGA1UEBhMC
VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28x
EjAQBgNVBAoTCUNlbGx1bG9pZDEbMBkGA1UEAxMSc2VydmVyLmV4YW1wbGUuY29t
MSEwHwYJKoZIhvcNAQkBFhJzZXJ2ZXJAZXhhbXBsZS5jb20wHhcNMTIxMTI1MTkx
NjAwWhcNMjIxMTIzMTkxNjAwWjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNh
bGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEjAQBgNVBAoTCUNlbGx1
bG9pZDEbMBkGA1UEAxMSc2VydmVyLmV4YW1wbGUuY29tMSEwHwYJKoZIhvcNAQkB
FhJzZXJ2ZXJAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQCpLs3Xg00RtoG4+SKaaNfw6Dve9d0Kkg0CNfU8AsxOgTIU1Qu8s+bzKkqe
66NfCa6T8VPpk9VbIlF2ONdgY4o8muV1q+mS6j2HDAtWPiDjP+9YOwGf/DT3LhSb
g8k+alL2cqe7B1XNUsNFEvQ+yQLlj9MWKb7nbYDM8aqdv46KGoDj9v9rfm4QiKwI
B6u/KoQG22YF7sT4O44jU/u20xcm3rV1Elg0gC/UP/YqnuMPCZYcK/Z9vYGtDJ6G
8OYDcPZSZBdkqlffhYBssSj3R7sTCqoh4ms08ukcGycbvUO+cWrPKnmySsGaCYtG
kp7QsH1ec7QGA01hZL2yL8CuJMUbAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBABE4
gYVSdC87NhpA49k0vcLLU7v7mU3a3no/vu1CIqQxzx8/xh26Qi3aGb1s9MgHpF2Z
NiB1irXER2tyz/F3qCi8OCo7eNsndmDjj4GnkBjEPTtqRxH9imRWw4bJyqwqFHcu
1kczCZa+2VFQFEL4ErGycPFKM59ppTcJ0IxbK7PCGzO75TRQoAl52+3Aob+oejPP
qFbiqNlV1T3EKa5yLdvOC5sLrEcfm3iMxmOtNVzp9OBhjXfm8Q1zgYs4VyJXzLMK
wf956w2YEbpTAAzNc53zly/Jhr4MnFsa9Mn1oYp9Rfjzw/qJtXw+a3PtEKrO4XNe
TsKHsAkj8XvUrhliiNQ=
-----END CERTIFICATE-----
27 changes: 27 additions & 0 deletions spec/fixtures/server.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAqS7N14NNEbaBuPkimmjX8Og73vXdCpINAjX1PALMToEyFNUL
vLPm8ypKnuujXwmuk/FT6ZPVWyJRdjjXYGOKPJrldavpkuo9hwwLVj4g4z/vWDsB
n/w09y4Um4PJPmpS9nKnuwdVzVLDRRL0PskC5Y/TFim+522AzPGqnb+OihqA4/b/
a35uEIisCAervyqEBttmBe7E+DuOI1P7ttMXJt61dRJYNIAv1D/2Kp7jDwmWHCv2
fb2BrQyehvDmA3D2UmQXZKpX34WAbLEo90e7EwqqIeJrNPLpHBsnG71DvnFqzyp5
skrBmgmLRpKe0LB9XnO0BgNNYWS9si/AriTFGwIDAQABAoIBAGKRoV4p4rIqOiQy
CuYZpY53T8KUToeFFk0ucMXY/33RqgMXKTJ1Ql50SmuS8GlDs9IALZqOBiWFth6B
+YHwHK84s+2+DmUJUnWnH8fMhM7CBknKfyTeBWHqGBmPS6WwvstVe8HtASGSUbCh
3WnjJWvoQtzLz6z4UK2XM4ea/ooY+hlcw6DM+jZuTstzLFE/9BPoHueaW8UemjaH
ZUXMKm3+I3iIjHszUUWM59bS9pOBn/YvIJbVE5wMIVCP2YXDCgfpV2Z4nDiAHppn
fnha2TzHzlPMgwhBpz06r6G8X+A6gJl98TDSK41nIMyXqiZ2aoALL3UOssAMfUHr
2y9CGdECgYEA27F1IyUW3JgqCeqZ7eCeT4emhAvyohzM5pzWI7C8ZosF14zFRpek
TgmjdTGMQ1EZVVkyj85RyvMm3MkcKOHetc5g2jJg3EkxvAV+PMs7yjpqg3itEjC6
vIhXLoXdq+FuruA2h4O0hi6yuf1FCQYtpNLTe49qetjsaWzwwowHwlMCgYEAxSRo
k+AdpoNXblnIhd0EaKjGAsHFrC039o7JqQe/mKAiXaGiidIDk5Vt/ChT6Qa6fiLq
cdysCn+tSCt/DdRrELZohc0ipuy5/agQmJgWoW7oay8ldzxHP9VevWo4UuqVudW9
evhKe0a9uXCrSimvZ5PJk91lmBx92FBeP6Y+qRkCgYAXQsvPQ88O3kGdOSzBJgY9
D3TPCGDRT1FWnYaC0uSvysp8jxgYKFgqNxUKhIuAWSbghYg397VrUqFrwRNtNLUa
9NYGZE0jJdDRQpeiIjaba+H5N57DjUtISPtKHrxgxYatl2nOoWBM0Mb1sF5N3UyZ
5gSkUYQJq8wkQXegcakkpwKBgEdvvgV3vMbN6SyvlB4NzL8wCTCOjtapPBI4A5Mg
n6jqvgk3vPI8C9e62jP5WQ6jxYhXlqTT1fOn+F6ihFO6mWFg99ckUl4ygeMMt5bT
5b9xtP7CAs2GJjtXUhFJIEfLgZ3pedPJjRPGupEr5qXlHQ5nWzAdlebczC1KUhy2
XRZhAoGAGA3SAAF79PK3c3+bOOviXxDFuH5TCBmbtEpJ+/jCbwR6Z8fMRswZJ3Gc
l8eNMsB+Kfif+806xAgLxsyhYuyvF6rE/V34GKjW22T1gwk6gY/rOgFn42jo8lwl
HFbSB+IG0+Go0m+0QmyRh7SyPvDNtyYzBFFdl9U8JYYGM0Nfgd0=
-----END RSA PRIVATE KEY-----
54 changes: 54 additions & 0 deletions spec/reel/ssl_server_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
require 'spec_helper'
require 'net/http'

describe Reel::SSLServer do
let(:example_ssl_port) { example_port + 1 }
let(:example_url) { "https://#{example_addr}:#{example_ssl_port}#{example_path}" }
let(:endpoint) { URI(example_url) }
let(:response_body) { "ohai thar" }

let(:server_cert) { fixture_dir.join("server.crt").read }
let(:server_key) { fixture_dir.join("server.key").read }

it "receives HTTP requests and sends responses" do
ex = nil

handler = proc do |connection|
begin
request = connection.request
request.method.should eq 'GET'
request.version.should eq "1.1"
request.url.should eq example_path

connection.respond :ok, response_body
rescue => ex
end
end

with_reel_sslserver(handler) do
http = Net::HTTP.new(endpoint.host, endpoint.port)
http.use_ssl = true

# FIXME: VERIFY_NONE is bad! Authenticate the server cert!
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(endpoint.path)
response = http.request(request)

response.body.should eq response_body
end

raise ex if ex
end

def with_reel_sslserver(handler, context = OpenSSL::SSL::SSLContext.new)
options = {
:cert => server_cert,
:key => server_key
}

server = Reel::SSLServer.new(example_addr, example_ssl_port, options, &handler)
yield server
ensure
server.terminate if server && server.alive?
end
end
10 changes: 8 additions & 2 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
require 'bundler/setup'
require 'reel'
require 'coveralls'
Coveralls.wear!

require 'bundler/setup'
require 'reel'
require 'pry'

logfile = File.open(File.expand_path("../../log/test.log", __FILE__), 'a')
Celluloid.logger = Logger.new(logfile)

def fixture_dir
Pathname.new File.expand_path("../fixtures", __FILE__)
end

def example_addr; '127.0.0.1'; end
def example_port; 1234; end
def example_path; "/example"; end
Expand Down

0 comments on commit 6732f22

Please sign in to comment.