aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2015-11-09 19:07:21 +0900
committerKazuki Yamaguchi <k@rhe.jp>2015-11-09 19:07:21 +0900
commit11be104f7ac9e2fe91bd5f82a1bb2489692cdce8 (patch)
treea3b99e935d6ad125dcac6ff657d88dd8d14f0381
parent4b9266ad29d6f8b344ea73b74b0184026902ed0f (diff)
downloadplum-11be104f7ac9e2fe91bd5f82a1bb2489692cdce8.tar.gz
rename {Connection,Stream}Error to Remote{Connection,Stream}Error and create Local*Error
-rw-r--r--lib/plum/connection.rb16
-rw-r--r--lib/plum/errors.rb12
-rw-r--r--lib/plum/flow_control.rb6
-rw-r--r--lib/plum/server/connection.rb2
-rw-r--r--lib/plum/server/http_connection.rb2
-rw-r--r--lib/plum/server/https_connection.rb2
-rw-r--r--lib/plum/stream.rb54
-rw-r--r--test/plum/connection/test_handle_frame.rb5
-rw-r--r--test/plum/test_connection.rb8
-rw-r--r--test/plum/test_error.rb3
-rw-r--r--test/plum/test_stream.rb28
-rw-r--r--test/utils/assertions.rb18
12 files changed, 96 insertions, 60 deletions
diff --git a/lib/plum/connection.rb b/lib/plum/connection.rb
index 1d47360..c31836a 100644
--- a/lib/plum/connection.rb
+++ b/lib/plum/connection.rb
@@ -51,7 +51,7 @@ module Plum
return if new_data.empty?
@buffer << new_data
consume_buffer
- rescue ConnectionError => e
+ rescue RemoteConnectionError => e
callback(:connection_error, e)
goaway(e.http2_error_type)
close
@@ -94,12 +94,12 @@ module Plum
def validate_received_frame(frame)
if @state == :waiting_settings && frame.type != :settings
- raise ConnectionError.new(:protocol_error)
+ raise RemoteConnectionError.new(:protocol_error)
end
if @state == :waiting_continuation
if frame.type != :continuation || frame.stream_id != @continuation_id
- raise ConnectionError.new(:protocol_error)
+ raise RemoteConnectionError.new(:protocol_error)
end
if frame.end_headers?
@state = :open
@@ -127,7 +127,7 @@ module Plum
def receive_control_frame(frame)
if frame.length > @local_settings[:max_frame_size]
- raise ConnectionError.new(:frame_size_error)
+ raise RemoteConnectionError.new(:frame_size_error)
end
case frame.type
@@ -140,7 +140,7 @@ module Plum
when :goaway
receive_goaway(frame)
when :data, :headers, :priority, :rst_stream, :push_promise, :continuation
- raise Plum::ConnectionError.new(:protocol_error)
+ raise Plum::RemoteConnectionError.new(:protocol_error)
else
# MUST ignore unknown frame type.
end
@@ -148,11 +148,11 @@ module Plum
def receive_settings(frame, send_ack: true)
if frame.ack?
- raise ConnectionError.new(:frame_size_error) if frame.length != 0
+ raise RemoteConnectionError.new(:frame_size_error) if frame.length != 0
callback(:settings_ack)
return
else
- raise ConnectionError.new(:frame_size_error) if frame.length % 6 != 0
+ raise RemoteConnectionError.new(:frame_size_error) if frame.length % 6 != 0
end
old_remote_settings = @remote_settings.dup
@@ -175,7 +175,7 @@ module Plum
end
def receive_ping(frame)
- raise Plum::ConnectionError.new(:frame_size_error) if frame.length != 8
+ raise Plum::RemoteConnectionError.new(:frame_size_error) if frame.length != 8
if frame.ack?
callback(:ping_ack)
diff --git a/lib/plum/errors.rb b/lib/plum/errors.rb
index d5cce48..3220c67 100644
--- a/lib/plum/errors.rb
+++ b/lib/plum/errors.rb
@@ -31,9 +31,6 @@ module Plum
ERROR_CODES[@http2_error_type]
end
end
- class ConnectionError < HTTPError; end
- class StreamError < HTTPError; end
-
class LegacyHTTPError < Error
attr_reader :headers, :data, :parser
@@ -44,7 +41,10 @@ module Plum
end
end
- # Client
- class LocalConnectionError < HTTPError; end
- class LocalStreamError < HTTPError; end
+ class RemoteHTTPError < HTTPError; end
+ class RemoteConnectionError < RemoteHTTPError; end
+ class RemoteStreamError < RemoteHTTPError; end
+ class LocalHTTPError < HTTPError; end
+ class LocalConnectionError < LocalHTTPError; end
+ class LocalStreamError < LocalHTTPError; end
end
diff --git a/lib/plum/flow_control.rb b/lib/plum/flow_control.rb
index cfb181d..ccb57dd 100644
--- a/lib/plum/flow_control.rb
+++ b/lib/plum/flow_control.rb
@@ -65,7 +65,7 @@ module Plum
if frame.type == :data
@recv_remaining_window -= frame.length
if @recv_remaining_window < 0
- local_error = (Connection === self) ? ConnectionError : StreamError
+ local_error = (Connection === self) ? RemoteConnectionError : RemoteStreamError
raise local_error.new(:flow_control_error)
end
end
@@ -82,7 +82,7 @@ module Plum
def receive_window_update(frame)
if frame.length != 4
- raise Plum::ConnectionError.new(:frame_size_error)
+ raise Plum::RemoteConnectionError.new(:frame_size_error)
end
r_wsi = frame.payload.uint32
@@ -90,7 +90,7 @@ module Plum
wsi = r_wsi # & ~(1 << 31)
if wsi == 0
- local_error = (Connection === self) ? ConnectionError : StreamError
+ local_error = (Connection === self) ? RemoteConnectionError : RemoteStreamError
raise local_error.new(:protocol_error)
end
diff --git a/lib/plum/server/connection.rb b/lib/plum/server/connection.rb
index 450dcf6..a82d4aa 100644
--- a/lib/plum/server/connection.rb
+++ b/lib/plum/server/connection.rb
@@ -29,7 +29,7 @@ module Plum
def negotiate!
unless CLIENT_CONNECTION_PREFACE.start_with?(@buffer.byteslice(0, 24))
- raise ConnectionError.new(:protocol_error) # (MAY) send GOAWAY. sending.
+ raise RemoteConnectionError.new(:protocol_error) # (MAY) send GOAWAY. sending.
end
if @buffer.bytesize >= 24
diff --git a/lib/plum/server/http_connection.rb b/lib/plum/server/http_connection.rb
index 7111bb4..cb49a29 100644
--- a/lib/plum/server/http_connection.rb
+++ b/lib/plum/server/http_connection.rb
@@ -23,7 +23,7 @@ module Plum
private
def negotiate!
super
- rescue ConnectionError
+ rescue RemoteConnectionError
# Upgrade from HTTP/1.1
offset = @_http_parser << @buffer
@buffer.byteshift(offset)
diff --git a/lib/plum/server/https_connection.rb b/lib/plum/server/https_connection.rb
index 09e360f..bac1b4b 100644
--- a/lib/plum/server/https_connection.rb
+++ b/lib/plum/server/https_connection.rb
@@ -10,7 +10,7 @@ module Plum
if @sock.respond_to?(:cipher) # OpenSSL::SSL::SSLSocket-like
if CIPHER_BLACKLIST.include?(@sock.cipher.first) # [cipher-suite, ssl-version, keylen, alglen]
on(:negotiated) {
- raise ConnectionError.new(:inadequate_security)
+ raise RemoteConnectionError.new(:inadequate_security)
}
end
end
diff --git a/lib/plum/stream.rb b/lib/plum/stream.rb
index 61c7cd5..87e228e 100644
--- a/lib/plum/stream.rb
+++ b/lib/plum/stream.rb
@@ -47,20 +47,21 @@ module Plum
when :push_promise
receive_push_promise(frame)
when :ping, :goaway, :settings
- raise ConnectionError.new(:protocol_error) # stream_id MUST be 0x00
+ raise RemoteConnectionError.new(:protocol_error) # stream_id MUST be 0x00
else
# MUST ignore unknown frame
end
- rescue StreamError => e
+ rescue RemoteStreamError => e
callback(:stream_error, e)
- close(e.http2_error_type)
+ send_immediately Frame.rst_stream(id, e.http2_error_type)
+ close
end
# Closes this stream. Sends RST_STREAM frame to the peer.
# @param error_type [Symbol] The error type to be contained in the RST_STREAM frame.
- def close(error_type = :no_error)
+ def close
@state = :closed
- send_immediately Frame.rst_stream(id, error_type)
+ callback(:close)
end
# @api private
@@ -70,7 +71,7 @@ module Plum
# @api private
def update_dependency(weight: nil, parent: nil, exclusive: nil)
- raise StreamError.new(:protocol_error, "A stream cannot depend on itself.") if parent == self
+ raise RemoteStreamError.new(:protocol_error, "A stream cannot depend on itself.") if parent == self
if weight
@weight = weight
@@ -102,9 +103,9 @@ module Plum
def validate_received_frame(frame)
if frame.length > @connection.local_settings[:max_frame_size]
if [:headers, :push_promise, :continuation].include?(frame.type)
- raise ConnectionError.new(:frame_size_error)
+ raise RemoteConnectionError.new(:frame_size_error)
else
- raise StreamError.new(:frame_size_error)
+ raise RemoteStreamError.new(:frame_size_error)
end
end
end
@@ -116,13 +117,13 @@ module Plum
def receive_data(frame)
if @state != :open && @state != :half_closed_local
- raise StreamError.new(:stream_closed)
+ raise RemoteStreamError.new(:stream_closed)
end
if frame.padded?
padding_length = frame.payload.uint8
if padding_length >= frame.length
- raise ConnectionError.new(:protocol_error, "padding is too long")
+ raise RemoteConnectionError.new(:protocol_error, "padding is too long")
end
callback(:data, frame.payload.byteslice(1, frame.length - padding_length - 1))
else
@@ -149,7 +150,7 @@ module Plum
end
if padding_length > payload.bytesize
- raise ConnectionError.new(:protocol_error, "padding is too long")
+ raise RemoteConnectionError.new(:protocol_error, "padding is too long")
end
frames.each do |frame|
@@ -159,7 +160,7 @@ module Plum
begin
decoded_headers = @connection.hpack_decoder.decode(payload)
rescue => e
- raise ConnectionError.new(:compression_error, e)
+ raise RemoteConnectionError.new(:compression_error, e)
end
callback(:headers, decoded_headers)
@@ -169,15 +170,15 @@ module Plum
def receive_headers(frame)
if @state == :reserved_local
- raise ConnectionError.new(:protocol_error)
+ raise RemoteConnectionError.new(:protocol_error)
elsif @state == :half_closed_remote
- raise StreamError.new(:stream_closed)
+ raise RemoteStreamError.new(:stream_closed)
elsif @state == :closed
- raise ConnectionError.new(:stream_closed)
+ raise RemoteConnectionError.new(:stream_closed)
elsif @state == :closed_implicitly
- raise ConnectionError.new(:protocol_error)
+ raise RemoteConnectionError.new(:protocol_error)
elsif @state == :idle && self.id.even?
- raise ConnectionError.new(:protocol_error)
+ raise RemoteConnectionError.new(:protocol_error)
end
@state = :open
@@ -195,10 +196,10 @@ module Plum
if promised_stream.state == :closed_implicitly
# 5.1.1 An endpoint that receives an unexpected stream identifier MUST respond with a connection error of type PROTOCOL_ERROR.
- raise ConnectionError.new(:protocol_error)
+ raise RemoteConnectionError.new(:protocol_error)
elsif promised_id.odd?
# 5.1.1 Streams initiated by the server MUST use even-numbered stream identifiers.
- raise ConnectionError.new(:protocol_error)
+ raise RemoteConnectionError.new(:protocol_error)
end
end
@@ -214,7 +215,7 @@ module Plum
def receive_priority(frame)
if frame.length != 5
- raise StreamError.new(:frame_size_error)
+ raise RemoteStreamError.new(:frame_size_error)
end
receive_priority_payload(frame.payload)
end
@@ -230,13 +231,18 @@ module Plum
def receive_rst_stream(frame)
if frame.length != 4
- raise ConnectionError.new(:frame_size_error)
+ raise RemoteConnectionError.new(:frame_size_error)
elsif @state == :idle
- raise ConnectionError.new(:protocol_error)
+ raise RemoteConnectionError.new(:protocol_error)
end
-
- callback(:rst_stream, frame)
@state = :closed # MUST NOT send RST_STREAM
+
+ error_code = frame.payload.uint32
+ if error_code > 0
+ raise LocalStreamError.new(HTTPError::ERROR_CODES.key(error_code))
+ else
+ callback(:rst_stream, frame)
+ end
end
# override EventEmitter
diff --git a/test/plum/connection/test_handle_frame.rb b/test/plum/connection/test_handle_frame.rb
index 6aa7db7..d1cc54e 100644
--- a/test/plum/connection/test_handle_frame.rb
+++ b/test/plum/connection/test_handle_frame.rb
@@ -62,7 +62,10 @@ class ServerConnectionHandleFrameTest < Minitest::Test
def test_server_handle_goaway_reply
open_server_connection {|con|
assert_no_error {
- con << Frame.goaway(1234, :stream_closed).assemble
+ begin
+ con << Frame.goaway(1, :stream_closed).assemble
+ rescue LocalHTTPError
+ end
}
assert_equal(:goaway, sent_frames.last.type)
}
diff --git a/test/plum/test_connection.rb b/test/plum/test_connection.rb
index f490a87..b1a4803 100644
--- a/test/plum/test_connection.rb
+++ b/test/plum/test_connection.rb
@@ -92,4 +92,12 @@ class ConnectionTest < Minitest::Test
assert_equal(:open, con.state)
}
end
+
+ def test_connection_local_error
+ open_server_connection { |con|
+ assert_raises(LocalConnectionError) {
+ con << Frame.goaway(0, :frame_size_error).assemble
+ }
+ }
+ end
end
diff --git a/test/plum/test_error.rb b/test/plum/test_error.rb
index 167538a..8eaa489 100644
--- a/test/plum/test_error.rb
+++ b/test/plum/test_error.rb
@@ -7,7 +7,6 @@ class ErrorTest < Minitest::Test
assert_equal(0x08, e.http2_error_code)
}
- test.call ConnectionError
- test.call StreamError
+ test.call HTTPError
end
end
diff --git a/test/plum/test_stream.rb b/test/plum/test_stream.rb
index 9df9a55..a9de58e 100644
--- a/test/plum/test_stream.rb
+++ b/test/plum/test_stream.rb
@@ -19,14 +19,34 @@ class StreamTest < Minitest::Test
}
end
- def test_stream_close
- open_new_stream(state: :half_closed_local) {|stream|
- stream.close(:frame_size_error)
+ def test_stream_remote_error
+ open_server_connection { |con|
+ stream = nil
+ con.on(:headers) { |s|
+ stream = s
+ raise RemoteStreamError.new(:frame_size_error)
+ }
+
+ assert_stream_error(:frame_size_error) {
+ con << Frame.headers(1, "", :end_headers).assemble
+ }
last = sent_frames.last
assert_equal(:rst_stream, last.type)
- assert_equal(StreamError.new(:frame_size_error).http2_error_code, last.payload.uint32)
+ assert_equal(HTTPError::ERROR_CODES[:frame_size_error], last.payload.uint32)
assert_equal(:closed, stream.state)
}
end
+
+ def test_stream_local_error
+ open_server_connection { |con|
+ stream = nil
+ con.on(:headers) { |s| stream = s }
+
+ con << Frame.headers(1, "", :end_headers).assemble
+ assert_raises(LocalStreamError) {
+ con << Frame.rst_stream(1, :frame_size_error).assemble
+ }
+ }
+ end
end
diff --git a/test/utils/assertions.rb b/test/utils/assertions.rb
index 71928ed..746d475 100644
--- a/test/utils/assertions.rb
+++ b/test/utils/assertions.rb
@@ -1,21 +1,21 @@
module CustomAssertions
def assert_connection_error(type, &blk)
- assert_http_error(Plum::ConnectionError, type, &blk)
+ assert_http_error(Plum::RemoteConnectionError, type, &blk)
end
def assert_stream_error(type, &blk)
- assert_http_error(Plum::StreamError, type, &blk)
+ assert_http_error(Plum::RemoteStreamError, type, &blk)
end
def assert_no_error(stream: nil, connection: nil, &blk)
- Plum::ConnectionError.reset
- Plum::StreamError.reset
+ Plum::RemoteConnectionError.reset
+ Plum::RemoteStreamError.reset
begin
blk.call
- rescue Plum::HTTPError
+ rescue Plum::RemoteHTTPError
end
- assert_nil(Plum::StreamError.last, "No stream error expected but raised: #{Plum::StreamError.last}")
- assert_nil(Plum::ConnectionError.last, "No connection error expected but raised: #{Plum::ConnectionError.last}")
+ assert_nil(Plum::RemoteStreamError.last, "No stream error expected but raised: #{Plum::RemoteStreamError.last}")
+ assert_nil(Plum::RemoteConnectionError.last, "No connection error expected but raised: #{Plum::RemoteConnectionError.last}")
end
def assert_frame(frame, **args)
@@ -56,5 +56,5 @@ module LastErrorExtension
base.reset
end
end
-Plum::ConnectionError.__send__(:prepend, LastErrorExtension)
-Plum::StreamError.__send__(:prepend, LastErrorExtension)
+Plum::RemoteConnectionError.__send__(:prepend, LastErrorExtension)
+Plum::RemoteStreamError.__send__(:prepend, LastErrorExtension)