nonnative 3.18.0 → 3.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5b12a0346b56caafe5c5c3b569be5d413f549881aaff7b11a5f32790fcdb9a8
4
- data.tar.gz: 34c07a08b757d56c2a03180f988c90227f1a4fa2b5a3e4f98dc0d893fd18eaa9
3
+ metadata.gz: 011e40916b32666c33c2a0374ee97c3e96d563cf950f5c68e12b8afa7c18e986
4
+ data.tar.gz: 7b21a33ad8fc14077751e679b66a14523c79c0783004934f55fa61ea5608e477
5
5
  SHA512:
6
- metadata.gz: 1bcbc6b9874a9ee048b4aac19382fc6d241f6d1ff616c787fede90c8957a8e51180dc8101aa41574e980098d1805937d7475e15212402b8f4cfb5a71d509091c
7
- data.tar.gz: 9efff6226af6557162861d81f43976bfcde15991aa736715e140f7bc22cae1a8a28a65ec18d332a5f09997fc95fb755d7418a9e4156118ba7152c8bc3fb6be39
6
+ metadata.gz: 0e24fea055ed0e972507bfcb8ebbdf2c604d41e1a6908333a1863f1ba44dd356ea518936d3d6076f73fb37d0c3a9f593b6321ef1392d51d6d1cdf4c145b5ad6d
7
+ data.tar.gz: ec70302587120b093bb506d5d324821e880b10e406974822f44e1efa7c3fdee29465847eb8f71466ab3806ddd0eb328f2e0788bca28196066c6b3636ce0edb83
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nonnative (3.18.0)
4
+ nonnative (3.19.0)
5
5
  concurrent-ruby (>= 1, < 2)
6
6
  config (>= 5, < 6)
7
7
  cucumber (>= 7, < 12)
data/README.md CHANGED
@@ -788,6 +788,7 @@ The `fault_injection` proxy allows you to simulate failures by injecting them. W
788
788
  Clients connect to the service `host`/`port`, while the proxy forwards traffic to nested `proxy.host`/`proxy.port`.
789
789
 
790
790
  - `close_all` - Closes the socket as soon as it connects.
791
+ - `reset_peer` - Resets the socket as soon as it connects, so clients observe a TCP reset (`Errno::ECONNRESET`) rather than the graceful close performed by `close_all`.
791
792
  - `delay` - Delays traffic on the connection. Defaults to 2 seconds and can be configured through options.
792
793
  - `timeout` - Accepts the connection and stalls traffic until reset or stop closes the connection, so clients exercise their own read timeout behavior.
793
794
  - `invalid_data` - Forwards client requests unchanged, then corrupts upstream responses before they reach the client.
@@ -801,6 +802,7 @@ name = 'name of service in configuration'
801
802
  service = Nonnative.pool.service_by_name(name)
802
803
 
803
804
  service.proxy.close_all # To use close_all.
805
+ service.proxy.reset_peer # To reset (RST) client connections.
804
806
  service.proxy.timeout # To stall traffic until reset or stop.
805
807
  service.proxy.reset # To reset it back to a good state.
806
808
  ```
@@ -809,6 +811,7 @@ Use the Cucumber proxy steps:
809
811
 
810
812
  ```cucumber
811
813
  Given I set the proxy for service 'service_1' to 'close_all'
814
+ Given I set the proxy for service 'service_1' to 'reset_peer'
812
815
  Given I set the proxy for service 'service_1' to 'timeout'
813
816
  Then I should reset the proxy for service 'service_1'
814
817
  ```
@@ -55,6 +55,7 @@ module Nonnative
55
55
  module ProxySteps
56
56
  PROXY_OPERATIONS = {
57
57
  'close_all' => :close_all,
58
+ 'reset_peer' => :reset_peer,
58
59
  'delay' => :delay,
59
60
  'timeout' => :timeout,
60
61
  'invalid_data' => :invalid_data,
@@ -10,6 +10,7 @@ module Nonnative
10
10
  # This class exposes a small public control surface for tests:
11
11
  #
12
12
  # - {#close_all}: close connections immediately on accept
13
+ # - {#reset_peer}: reset connections immediately on accept (TCP RST rather than a graceful close)
13
14
  # - {#delay}: delay reads by a configured duration (default: 2 seconds)
14
15
  # - {#timeout}: accept connections and keep them silent until clients time out
15
16
  # - {#invalid_data}: forward requests unchanged and mutate upstream responses before they reach clients
@@ -99,6 +100,16 @@ module Nonnative
99
100
  apply_state :close_all
100
101
  end
101
102
 
103
+ # Forces new connections to be reset immediately.
104
+ #
105
+ # Unlike {#close_all}, which closes the socket gracefully (FIN), this closes the accepted socket
106
+ # with a zero linger timeout so clients observe a TCP reset (`Errno::ECONNRESET`).
107
+ #
108
+ # @return [void]
109
+ def reset_peer
110
+ apply_state :reset_peer
111
+ end
112
+
102
113
  # Delays reads before forwarding.
103
114
  #
104
115
  # The delay duration is controlled by `service.proxy.options[:delay]` and defaults to 2 seconds.
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nonnative
4
+ # Socket-pair variant used by the fault-injection proxy to simulate an abrupt connection reset.
5
+ #
6
+ # When active, the proxy accepts a TCP connection and closes it with a zero linger timeout, so the
7
+ # kernel sends a TCP RST instead of a graceful FIN. Clients observe a reset ("connection reset by
8
+ # peer", `Errno::ECONNRESET`) rather than a clean end-of-stream, which is distinct from the graceful
9
+ # close performed by {Nonnative::CloseAllSocketPair}.
10
+ #
11
+ # This behavior is enabled by calling {Nonnative::FaultInjectionProxy#reset_peer}.
12
+ #
13
+ # @see Nonnative::FaultInjectionProxy
14
+ # @see Nonnative::SocketPairFactory
15
+ # @see Nonnative::SocketPair
16
+ # @see Nonnative::CloseAllSocketPair
17
+ class ResetPeerSocketPair < SocketPair
18
+ # Resets the accepted socket by closing it with a zero linger timeout, forcing a TCP RST.
19
+ #
20
+ # @param local_socket [TCPSocket] the accepted client socket
21
+ # @return [void]
22
+ def connect(local_socket)
23
+ Nonnative.logger.info "resetting socket '#{local_socket.inspect}' for 'reset_peer' pair"
24
+
25
+ local_socket.setsockopt(Socket::Option.linger(true, 0))
26
+ local_socket.close
27
+ end
28
+ end
29
+ end
@@ -9,6 +9,7 @@ module Nonnative
9
9
  # Proxy states are mapped as follows:
10
10
  # - `:none` (or any unknown value) -> {Nonnative::SocketPair} (pass-through)
11
11
  # - `:close_all` -> {Nonnative::CloseAllSocketPair}
12
+ # - `:reset_peer` -> {Nonnative::ResetPeerSocketPair}
12
13
  # - `:delay` -> {Nonnative::DelaySocketPair}
13
14
  # - `:timeout` -> {Nonnative::TimeoutSocketPair}
14
15
  # - `:invalid_data` -> {Nonnative::InvalidDataSocketPair}
@@ -16,6 +17,7 @@ module Nonnative
16
17
  # @see Nonnative::FaultInjectionProxy
17
18
  # @see Nonnative::SocketPair
18
19
  # @see Nonnative::CloseAllSocketPair
20
+ # @see Nonnative::ResetPeerSocketPair
19
21
  # @see Nonnative::DelaySocketPair
20
22
  # @see Nonnative::TimeoutSocketPair
21
23
  # @see Nonnative::InvalidDataSocketPair
@@ -23,13 +25,15 @@ module Nonnative
23
25
  class << self
24
26
  # Creates a socket-pair instance for the given proxy state.
25
27
  #
26
- # @param kind [Symbol] proxy state (e.g. `:none`, `:close_all`, `:delay`, `:timeout`, `:invalid_data`)
28
+ # @param kind [Symbol] proxy state (e.g. `:none`, `:close_all`, `:reset_peer`, `:delay`, `:timeout`, `:invalid_data`)
27
29
  # @param proxy [Nonnative::ConfigurationProxy] proxy configuration (host/port/options)
28
30
  # @return [Nonnative::SocketPair] a socket-pair implementation instance
29
31
  def create(kind, proxy)
30
32
  pair = case kind
31
33
  when :close_all
32
34
  CloseAllSocketPair
35
+ when :reset_peer
36
+ ResetPeerSocketPair
33
37
  when :delay
34
38
  DelaySocketPair
35
39
  when :timeout
@@ -4,5 +4,5 @@ module Nonnative
4
4
  # The current gem version.
5
5
  #
6
6
  # @return [String]
7
- VERSION = '3.18.0'
7
+ VERSION = '3.19.0'
8
8
  end
data/lib/nonnative.rb CHANGED
@@ -111,6 +111,7 @@ require 'nonnative/no_proxy'
111
111
  require 'nonnative/fault_injection_proxy'
112
112
  require 'nonnative/socket_pair'
113
113
  require 'nonnative/close_all_socket_pair'
114
+ require 'nonnative/reset_peer_socket_pair'
114
115
  require 'nonnative/delay_socket_pair'
115
116
  require 'nonnative/timeout_socket_pair'
116
117
  require 'nonnative/invalid_data_socket_pair'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nonnative
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.18.0
4
+ version: 3.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alejandro Falkowski
@@ -446,6 +446,7 @@ files:
446
446
  - lib/nonnative/process.rb
447
447
  - lib/nonnative/proxy.rb
448
448
  - lib/nonnative/proxy_factory.rb
449
+ - lib/nonnative/reset_peer_socket_pair.rb
449
450
  - lib/nonnative/runner.rb
450
451
  - lib/nonnative/server.rb
451
452
  - lib/nonnative/service.rb