From de62f5962e9047e867eb39ef933738ea3b9722c1 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Mon, 16 Nov 2015 18:48:35 +0900 Subject: server/connection: reorganize subclasses * HTTPSServerConnection is renamed to SSLSocketServerConnection * HTTPServerConnection now accepts writer Proc (Method) instead of IO --- test/plum/client/test_client.rb | 2 +- test/plum/server/test_connection.rb | 91 +++++++++++++++++++++++++++++++ test/plum/server/test_http_connection.rb | 10 ++-- test/plum/server/test_https_connection.rb | 91 ------------------------------- test/utils/server.rb | 8 +-- 5 files changed, 102 insertions(+), 100 deletions(-) create mode 100644 test/plum/server/test_connection.rb delete mode 100644 test/plum/server/test_https_connection.rb (limited to 'test') diff --git a/test/plum/client/test_client.rb b/test/plum/client/test_client.rb index 214e30f..35c0638 100644 --- a/test/plum/client/test_client.rb +++ b/test/plum/client/test_client.rb @@ -112,7 +112,7 @@ class ClientTest < Minitest::Test begin Timeout.timeout(1) { sock = ssl_server.accept - plum = HTTPSServerConnection.new(sock) + plum = ServerConnection.new(sock.method(:write)) plum.on(:stream) { |stream| headers = data = nil diff --git a/test/plum/server/test_connection.rb b/test/plum/server/test_connection.rb new file mode 100644 index 0000000..4a45eaa --- /dev/null +++ b/test/plum/server/test_connection.rb @@ -0,0 +1,91 @@ +require "test_helper" + +using Plum::BinaryString + +class HTTPSConnectionNegotiationTest < Minitest::Test + def test_server_must_raise_cprotocol_error_invalid_magic_short + con = ServerConnection.new(StringIO.new.method(:write)) + assert_connection_error(:protocol_error) { + con << "HELLO" + } + end + + def test_server_must_raise_cprotocol_error_invalid_magic_long + con = ServerConnection.new(StringIO.new.method(:write)) + assert_connection_error(:protocol_error) { + con << ("HELLO" * 100) # over 24 + } + end + + def test_server_must_raise_cprotocol_error_non_settings_after_magic + con = ServerConnection.new(StringIO.new.method(:write)) + con << Connection::CLIENT_CONNECTION_PREFACE + assert_connection_error(:protocol_error) { + con << Frame.new(type: :window_update, stream_id: 0, payload: "".push_uint32(1)).assemble + } + end + + def test_server_accept_fragmented_magic + magic = Connection::CLIENT_CONNECTION_PREFACE + con = ServerConnection.new(StringIO.new.method(:write)) + assert_no_error { + con << magic[0...5] + con << magic[5..-1] + con << Frame.new(type: :settings, stream_id: 0).assemble + } + end + + def test_inadequate_security_ssl_socket + run = false + + ctx = OpenSSL::SSL::SSLContext.new + ctx.alpn_select_cb = -> protocols { "h2" } + ctx.cert = TLS_CERT + ctx.key = TLS_KEY + tcp_server = TCPServer.new("127.0.0.1", LISTEN_PORT) + ssl_server = OpenSSL::SSL::SSLServer.new(tcp_server, ctx) + + server_thread = Thread.new { + begin + Timeout.timeout(3) { + sock = ssl_server.accept + plum = SSLSocketServerConnection.new(sock) + assert_connection_error(:inadequate_security) { + run = true + while !sock.closed? && !sock.eof? + plum << sock.readpartial(1024) + end + } + } + rescue Timeout::Error + flunk "server timeout" + rescue => e + flunk e + ensure + tcp_server.close + end + } + client_thread = Thread.new { + sock = TCPSocket.new("127.0.0.1", LISTEN_PORT) + begin + ctx = OpenSSL::SSL::SSLContext.new.tap {|ctx| + ctx.alpn_protocols = ["h2"] + ctx.ciphers = "AES256-GCM-SHA384" + } + ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx) + ssl.connect + ssl.write Connection::CLIENT_CONNECTION_PREFACE + ssl.write Frame.settings.assemble + sleep + rescue => e + flunk e + ensure + sock.close + end + } + server_thread.join + client_thread.kill + + flunk "test not run" unless run + end +end diff --git a/test/plum/server/test_http_connection.rb b/test/plum/server/test_http_connection.rb index bd586a5..3093d5b 100644 --- a/test/plum/server/test_http_connection.rb +++ b/test/plum/server/test_http_connection.rb @@ -5,7 +5,8 @@ using Plum::BinaryString class HTTPConnectionNegotiationTest < Minitest::Test ## with Prior Knowledge (same as over TLS) def test_server_must_raise_cprotocol_error_non_settings_after_magic - con = HTTPServerConnection.new(StringIO.new) + io = StringIO.new + con = HTTPServerConnection.new(io.method(:write)) con << Connection::CLIENT_CONNECTION_PREFACE assert_connection_error(:protocol_error) { con << Frame.new(type: :window_update, stream_id: 0, payload: "".push_uint32(1)).assemble @@ -14,7 +15,8 @@ class HTTPConnectionNegotiationTest < Minitest::Test def test_server_accept_fragmented_magic magic = Connection::CLIENT_CONNECTION_PREFACE - con = HTTPServerConnection.new(StringIO.new) + io = StringIO.new + con = HTTPServerConnection.new(io.method(:write)) assert_no_error { con << magic[0...5] con << magic[5..-1] @@ -25,7 +27,7 @@ class HTTPConnectionNegotiationTest < Minitest::Test ## with HTTP/1.1 Upgrade def test_server_accept_upgrade io = StringIO.new - con = HTTPServerConnection.new(io) + con = HTTPServerConnection.new(io.method(:write)) heads = nil con.on(:headers) {|_, _h| heads = _h.to_h } req = "GET / HTTP/1.1\r\n" << @@ -47,7 +49,7 @@ class HTTPConnectionNegotiationTest < Minitest::Test def test_server_deny_non_upgrade io = StringIO.new - con = HTTPServerConnection.new(io) + con = HTTPServerConnection.new(io.method(:write)) req = "GET / HTTP/1.1\r\n" << "Host: rhe.jp\r\n" << "User-Agent: nya\r\n" << diff --git a/test/plum/server/test_https_connection.rb b/test/plum/server/test_https_connection.rb deleted file mode 100644 index d227f73..0000000 --- a/test/plum/server/test_https_connection.rb +++ /dev/null @@ -1,91 +0,0 @@ -require "test_helper" - -using Plum::BinaryString - -class HTTPSConnectionNegotiationTest < Minitest::Test - def test_server_must_raise_cprotocol_error_invalid_magic_short - con = HTTPSServerConnection.new(StringIO.new) - assert_connection_error(:protocol_error) { - con << "HELLO" - } - end - - def test_server_must_raise_cprotocol_error_invalid_magic_long - con = HTTPSServerConnection.new(StringIO.new) - assert_connection_error(:protocol_error) { - con << ("HELLO" * 100) # over 24 - } - end - - def test_server_must_raise_cprotocol_error_non_settings_after_magic - con = HTTPSServerConnection.new(StringIO.new) - con << Connection::CLIENT_CONNECTION_PREFACE - assert_connection_error(:protocol_error) { - con << Frame.new(type: :window_update, stream_id: 0, payload: "".push_uint32(1)).assemble - } - end - - def test_server_accept_fragmented_magic - magic = Connection::CLIENT_CONNECTION_PREFACE - con = HTTPSServerConnection.new(StringIO.new) - assert_no_error { - con << magic[0...5] - con << magic[5..-1] - con << Frame.new(type: :settings, stream_id: 0).assemble - } - end - - def test_inadequate_security_ssl_socket - run = false - - ctx = OpenSSL::SSL::SSLContext.new - ctx.alpn_select_cb = -> protocols { "h2" } - ctx.cert = TLS_CERT - ctx.key = TLS_KEY - tcp_server = TCPServer.new("127.0.0.1", LISTEN_PORT) - ssl_server = OpenSSL::SSL::SSLServer.new(tcp_server, ctx) - - server_thread = Thread.new { - begin - Timeout.timeout(3) { - sock = ssl_server.accept - plum = HTTPSServerConnection.new(sock) - assert_connection_error(:inadequate_security) { - run = true - while !sock.closed? && !sock.eof? - plum << sock.readpartial(1024) - end - } - } - rescue Timeout::Error - flunk "server timeout" - rescue => e - flunk e - ensure - tcp_server.close - end - } - client_thread = Thread.new { - sock = TCPSocket.new("127.0.0.1", LISTEN_PORT) - begin - ctx = OpenSSL::SSL::SSLContext.new.tap {|ctx| - ctx.alpn_protocols = ["h2"] - ctx.ciphers = "AES256-GCM-SHA384" - } - ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx) - ssl.connect - ssl.write Connection::CLIENT_CONNECTION_PREFACE - ssl.write Frame.settings.assemble - sleep - rescue => e - flunk e - ensure - sock.close - end - } - server_thread.join - client_thread.kill - - flunk "test not run" unless run - end -end diff --git a/test/utils/server.rb b/test/utils/server.rb index afb9f57..5f1baa7 100644 --- a/test/utils/server.rb +++ b/test/utils/server.rb @@ -2,8 +2,8 @@ require "timeout" module ServerUtils def open_server_connection(scheme = :https) - io = StringIO.new - @_con = (scheme == :https ? HTTPSServerConnection : HTTPServerConnection).new(io) + @_io = StringIO.new + @_con = (scheme == :https ? ServerConnection : HTTPServerConnection).new(@_io.method(:write)) @_con << Connection::CLIENT_CONNECTION_PREFACE @_con << Frame.new(type: :settings, stream_id: 0).assemble if block_given? @@ -30,8 +30,8 @@ module ServerUtils end end - def sent_frames(con = nil) - resp = (con || @_con).sock.string.dup.force_encoding(Encoding::BINARY) + def sent_frames(io = nil) + resp = (io || @_io).string.dup.force_encoding(Encoding::BINARY) frames = [] while f = Frame.parse!(resp) frames << f -- cgit v1.2.3