Skip to content
Merged
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
80 changes: 80 additions & 0 deletions spec/std/http/server/server_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,86 @@ module HTTP
end
server.close unless server.closed?
end

describe "with URI" do
it "accepts URI" do
server = Server.new { }

begin
address = server.bind URI.parse("tcp://127.0.0.1:8081")
address.should eq Socket::IPAddress.new("127.0.0.1", 8081)
ensure
server.close
end
end

it "accepts String" do
server = Server.new { }

begin
address = server.bind "tcp://127.0.0.1:8081"
address.should eq Socket::IPAddress.new("127.0.0.1", 8081)
ensure
server.close
end
end

it "parses TCP" do
server = Server.new { }

begin
address = server.bind "tcp://127.0.0.1:8081"
address.should eq Socket::IPAddress.new("127.0.0.1", 8081)
ensure
server.close
end
end

it "parses SSL" do
server = Server.new { }

private_key = datapath("openssl", "openssl.key")
certificate = datapath("openssl", "openssl.crt")

begin
expect_raises(ArgumentError, "missing CA certificate") do
server.bind "ssl://127.0.0.1:8081?key=#{private_key}&cert=#{certificate}&verify_mode=force-peer"
end

address = server.bind "ssl://127.0.0.1:8081?key=#{private_key}&cert=#{certificate}&ca=#{certificate}"
address.should eq Socket::IPAddress.new("127.0.0.1", 8081)
ensure
server.close
end
end

it "fails SSL with invalid params" do
server = Server.new { }

private_key = datapath("openssl", "openssl.key")
certificate = datapath("openssl", "openssl.crt")

begin
expect_raises(ArgumentError, "missing private key") { server.bind "ssl://127.0.0.1:8081" }
expect_raises(OpenSSL::Error, "No such file or directory") { server.bind "ssl://127.0.0.1:8081?key=foo.key" }
expect_raises(ArgumentError, "missing certificate") { server.bind "ssl://127.0.0.1:8081?key=#{private_key}" }
ensure
server.close
end
end

it "fails with unknown scheme" do
server = Server.new { }

begin
expect_raises(ArgumentError, "Unsupported socket type: udp") do
server.bind "udp://127.0.0.1:8081"
end
ensure
server.close
end
end
end
end

describe "#bind_ssl" do
Expand Down
49 changes: 49 additions & 0 deletions spec/std/openssl/ssl/context_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,53 @@ describe OpenSSL::SSL::Context do
it "calls #finalize on insecure server context" do
assert_finalizes(:insecure_server_ctx) { OpenSSL::SSL::Context::Server.insecure }
end

describe ".from_hash" do
it "builds" do
private_key = datapath("openssl", "openssl.key")
certificate = datapath("openssl", "openssl.crt")

context = OpenSSL::SSL::Context::Client.from_hash({"key" => private_key, "cert" => certificate, "verify_mode" => "none"})
context.verify_mode.should eq OpenSSL::SSL::VerifyMode::NONE

context = OpenSSL::SSL::Context::Server.from_hash({"key" => private_key, "cert" => certificate})
context.verify_mode.should eq OpenSSL::SSL::VerifyMode::NONE

context = OpenSSL::SSL::Context::Client.from_hash({"key" => private_key, "cert" => certificate, "ca" => certificate})
context.verify_mode.should eq OpenSSL::SSL::VerifyMode::PEER

context = OpenSSL::SSL::Context::Client.from_hash({"key" => private_key, "cert" => certificate, "ca" => File.dirname(certificate)})
context.verify_mode.should eq OpenSSL::SSL::VerifyMode::PEER
end

it "errors" do
private_key = datapath("openssl", "openssl.key")
certificate = datapath("openssl", "openssl.crt")

expect_raises(ArgumentError, "missing private key") do
OpenSSL::SSL::Context::Client.from_hash({} of String => String)
end
expect_raises(OpenSSL::Error, "SSL_CTX_use_PrivateKey_file: error:02001002:system library:fopen:No such file or directory") do
OpenSSL::SSL::Context::Client.from_hash({"key" => "foo"})
end
expect_raises(ArgumentError, "missing certificate") do
OpenSSL::SSL::Context::Client.from_hash({"key" => private_key})
end
expect_raises(OpenSSL::Error, "SSL_CTX_use_certificate_chain_file: error:02001002:system library:fopen:No such file or directory") do
OpenSSL::SSL::Context::Client.from_hash({"key" => private_key, "cert" => "foo"})
end
expect_raises(ArgumentError, "Invalid SSL context: missing CA certificate") do
OpenSSL::SSL::Context::Client.from_hash({"key" => private_key, "cert" => certificate})
end
expect_raises(ArgumentError, %(Invalid SSL context: unknown verify mode "foo")) do
OpenSSL::SSL::Context::Client.from_hash({"key" => private_key, "cert" => certificate, "verify_mode" => "foo"})
end
expect_raises(ArgumentError, "Invalid SSL context: missing CA certificate") do
OpenSSL::SSL::Context::Client.from_hash({"key" => private_key, "cert" => certificate, "verify_mode" => "peer"})
end
expect_raises(OpenSSL::Error, "SSL_CTX_load_verify_locations: error:02001002:system library:fopen:No such file or directory") do
OpenSSL::SSL::Context::Client.from_hash({"key" => private_key, "cert" => certificate, "ca" => "foo"})
end
end
end
end
163 changes: 163 additions & 0 deletions spec/std/socket/address_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
require "spec"
require "socket/address"

describe Socket::Address do
describe ".parse" do
it "accepts URI" do
address = Socket::Address.parse URI.parse("tcp://192.168.0.1:8081")
address.should eq Socket::IPAddress.new("192.168.0.1", 8081)
end

it "parses TCP" do
address = Socket::Address.parse "tcp://192.168.0.1:8081"
address.should eq Socket::IPAddress.new("192.168.0.1", 8081)
end

it "parses UDP" do
address = Socket::Address.parse "udp://192.168.0.1:8081"
address.should eq Socket::IPAddress.new("192.168.0.1", 8081)
end

it "parses UNIX" do
address = Socket::Address.parse "unix://socket.sock"
address.should eq Socket::UNIXAddress.new("socket.sock")
end

it "fails with unknown scheme" do
expect_raises(Socket::Error, "Unsupported address type: ssl") do
Socket::Address.parse "ssl://192.168.0.1:8081"
end
end
end
end

describe Socket::IPAddress do
it "transforms an IPv4 address into a C struct and back" do
addr1 = Socket::IPAddress.new("127.0.0.1", 8080)
addr2 = Socket::IPAddress.from(addr1.to_unsafe, addr1.size)

addr2.family.should eq(addr1.family)
addr2.port.should eq(addr1.port)
typeof(addr2.address).should eq(String)
addr2.address.should eq(addr1.address)
end

it "transforms an IPv6 address into a C struct and back" do
addr1 = Socket::IPAddress.new("2001:db8:8714:3a90::12", 8080)
addr2 = Socket::IPAddress.from(addr1.to_unsafe, addr1.size)

addr2.family.should eq(addr1.family)
addr2.port.should eq(addr1.port)
typeof(addr2.address).should eq(String)
addr2.address.should eq(addr1.address)
end

it "won't resolve domains" do
expect_raises(Socket::Error, /Invalid IP address/) do
Socket::IPAddress.new("localhost", 1234)
end
end

it "to_s" do
Socket::IPAddress.new("127.0.0.1", 80).to_s.should eq("127.0.0.1:80")
Socket::IPAddress.new("2001:db8:8714:3a90::12", 443).to_s.should eq("[2001:db8:8714:3a90::12]:443")
end

describe ".parse" do
it "parses IPv4" do
address = Socket::IPAddress.parse "ip://192.168.0.1:8081"
address.should eq Socket::IPAddress.new("192.168.0.1", 8081)
end

it "parses IPv6" do
address = Socket::IPAddress.parse "ip://[::1]:8081"
address.should eq Socket::IPAddress.new("::1", 8081)
end

it "fails host name" do
expect_raises(Socket::Error, "Invalid IP address: example.com") do
Socket::IPAddress.parse "ip://example.com:8081"
end
end

it "ignores path and params" do
address = Socket::IPAddress.parse "ip://192.168.0.1:8081/foo?bar=baz"
address.should eq Socket::IPAddress.new("192.168.0.1", 8081)
end

it "fails with missing host" do
expect_raises(Socket::Error, "Invalid IP address: missing host") do
Socket::IPAddress.parse "ip:///path"
end
end

it "fails with missing port" do
expect_raises(Socket::Error, "Invalid IP address: missing port") do
Socket::IPAddress.parse "ip://127.0.0.1"
end
end
end
end

describe Socket::UNIXAddress do
it "transforms into a C struct and back" do
path = "unix_address.sock"

addr1 = Socket::UNIXAddress.new(path)
addr2 = Socket::UNIXAddress.from(addr1.to_unsafe, addr1.size)

addr2.family.should eq(addr1.family)
addr2.path.should eq(addr1.path)
addr2.to_s.should eq(path)
end

it "raises when path is too long" do
path = "unix_address-too-long-#{("a" * 2048)}.sock"

expect_raises(ArgumentError, "Path size exceeds the maximum size") do
Socket::UNIXAddress.new(path)
end
end

it "to_s" do
Socket::UNIXAddress.new("some_path").to_s.should eq("some_path")
end

describe ".parse" do
it "parses relative" do
address = Socket::UNIXAddress.parse "unix://foo.sock"
address.should eq Socket::UNIXAddress.new("foo.sock")
end

it "parses relative subpath" do
address = Socket::UNIXAddress.parse "unix://foo/bar.sock"
address.should eq Socket::UNIXAddress.new("foo/bar.sock")
end

it "parses relative dot" do
address = Socket::UNIXAddress.parse "unix://./bar.sock"
address.should eq Socket::UNIXAddress.new("./bar.sock")
end

it "relative with" do
address = Socket::UNIXAddress.parse "unix://foo:21/bar.sock"
address.should eq Socket::UNIXAddress.new("foo:21/bar.sock")
end

it "parses absolute" do
address = Socket::UNIXAddress.parse "unix:///foo.sock"
address.should eq Socket::UNIXAddress.new("/foo.sock")
end

it "ignores params" do
address = Socket::UNIXAddress.parse "unix:///foo.sock?bar=baz"
address.should eq Socket::UNIXAddress.new("/foo.sock")
end

it "fails with missing path" do
expect_raises(Socket::Error, "Invalid UNIX address: missing path") do
Socket::UNIXAddress.parse "unix://?foo=bar"
end
end
end
end
58 changes: 0 additions & 58 deletions spec/std/socket_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -148,64 +148,6 @@ describe Socket::Addrinfo do
end
end

describe Socket::IPAddress do
it "transforms an IPv4 address into a C struct and back" do
addr1 = Socket::IPAddress.new("127.0.0.1", 8080)
addr2 = Socket::IPAddress.from(addr1.to_unsafe, addr1.size)

addr2.family.should eq(addr1.family)
addr2.port.should eq(addr1.port)
typeof(addr2.address).should eq(String)
addr2.address.should eq(addr1.address)
end

it "transforms an IPv6 address into a C struct and back" do
addr1 = Socket::IPAddress.new("2001:db8:8714:3a90::12", 8080)
addr2 = Socket::IPAddress.from(addr1.to_unsafe, addr1.size)

addr2.family.should eq(addr1.family)
addr2.port.should eq(addr1.port)
typeof(addr2.address).should eq(String)
addr2.address.should eq(addr1.address)
end

it "won't resolve domains" do
expect_raises(Socket::Error, /Invalid IP address/) do
Socket::IPAddress.new("localhost", 1234)
end
end

it "to_s" do
Socket::IPAddress.new("127.0.0.1", 80).to_s.should eq("127.0.0.1:80")
Socket::IPAddress.new("2001:db8:8714:3a90::12", 443).to_s.should eq("[2001:db8:8714:3a90::12]:443")
end
end

describe Socket::UNIXAddress do
it "transforms into a C struct and back" do
path = "unix_address.sock"

addr1 = Socket::UNIXAddress.new(path)
addr2 = Socket::UNIXAddress.from(addr1.to_unsafe, addr1.size)

addr2.family.should eq(addr1.family)
addr2.path.should eq(addr1.path)
addr2.to_s.should eq(path)
end

it "raises when path is too long" do
path = "unix_address-too-long-#{("a" * 2048)}.sock"

expect_raises(ArgumentError, "Path size exceeds the maximum size") do
Socket::UNIXAddress.new(path)
end
end

it "to_s" do
Socket::UNIXAddress.new("some_path").to_s.should eq("some_path")
end
end

describe UNIXServer do
it "raises when path is too long" do
with_tempfile("unix_server-too_long-#{("a" * 2048)}.sock") do |path|
Expand Down
Loading