Skip to content

Commit

Permalink
Add SSLServer
Browse files Browse the repository at this point in the history
  • Loading branch information
straight-shoota committed Apr 17, 2018
1 parent 01a5126 commit 5bc5c87
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 1 deletion.
75 changes: 75 additions & 0 deletions spec/std/socket/ssl_server_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
require "spec"
require "socket"
require "../../support/ssl"

describe SSLServer do
it "sync_close" do
TCPServer.open(0) do |tcp_server|
context = OpenSSL::SSL::Context::Server.new
ssl_server = SSLServer.new(tcp_server, context)

ssl_server.close

tcp_server.closed?.should be_true
end
end

it "don't sync_close" do
TCPServer.open(0) do |tcp_server|
context = OpenSSL::SSL::Context::Server.new
ssl_server = SSLServer.new(tcp_server, context, sync_close: false)
ssl_server.context.should eq context

ssl_server.close

tcp_server.closed?.should be_false
end
end

it ".new" do
context = OpenSSL::SSL::Context::Server.new
TCPServer.open(0) do |tcp_server|
ssl_server = SSLServer.new tcp_server, context, sync_close: false

ssl_server.context.should eq context
ssl_server.wrapped.should eq tcp_server
ssl_server.sync_close?.should be_false
end
end

it ".open" do
context = OpenSSL::SSL::Context::Server.new
TCPServer.open(0) do |tcp_server|
ssl_server = nil
SSLServer.open tcp_server, context do |server|
server.wrapped.should eq tcp_server
ssl_server = server
end

ssl_server.try(&.closed?).should be_true
tcp_server.closed?.should be_true
end
end

describe "#accept?" do
it "accepts" do
tcp_server = TCPServer.new(0)

server_context, client_context = ssl_context_pair

SSLServer.open tcp_server, server_context do |server|
spawn do
client = server.accept?
client.should_not be_nil
client = client.not_nil!
client.gets.should eq "Hello, SSL!"
client.close
end

OpenSSL::SSL::Socket::Client.open(TCPSocket.new(tcp_server.local_address.address, tcp_server.local_address.port), client_context) do |socket|
socket.puts "Hello, SSL!"
end
end
end
end
end
10 changes: 10 additions & 0 deletions spec/support/ssl.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
def ssl_context_pair
server_context = OpenSSL::SSL::Context::Server.new
server_context.certificate_chain = File.join("spec", "std", "openssl", "ssl", "openssl.crt")
server_context.private_key = File.join("spec", "std", "openssl", "ssl", "openssl.key")

client_context = OpenSSL::SSL::Context::Client.new
client_context.verify_mode = OpenSSL::SSL::VerifyMode::NONE

{server_context, client_context}
end
4 changes: 3 additions & 1 deletion src/http/server.cr
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,9 @@ class HTTP::Server
end

private def handle_client(io : IO)
io.sync = false
if io.is_a?(IO::Buffered)
io.sync = false
end

{% if !flag?(:without_openssl) %}
if tls = @tls
Expand Down
42 changes: 42 additions & 0 deletions src/socket/ssl_server.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
require "openssl"

class SSLServer
include Socket::Server

getter wrapped : Socket::Server
getter context : OpenSSL::SSL::Context::Server

# If `#sync_close?` is `true`, closing this server will
# close the wrapped server.
property? sync_close : Bool

getter? closed : Bool = false

def initialize(@wrapped : Socket::Server, @context : OpenSSL::SSL::Context::Server = OpenSSL::SSL::Context::Server.new, @sync_close : Bool = true)
end

def self.open(wrapped : Socket::Server, context : OpenSSL::SSL::Context::Server = OpenSSL::SSL::Context::Server.new, sync_close : Bool = true)
server = new(wrapped, context, sync_close)

begin
yield server
ensure
server.close
end
end

def accept? : OpenSSL::SSL::Socket::Server?
if socket = @wrapped.accept?
OpenSSL::SSL::Socket::Server.new(socket, @context, sync_close: @sync_close)
end
end

def close
return if @closed
@closed = true

@wrapped.close if @sync_close
end

delegate local_address, remote_address, to: @wrapped
end

0 comments on commit 5bc5c87

Please sign in to comment.