netpump 1.0.0 → 1.0.2

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: 298b321a2b63596d5247b8d8cd807722c5062249f8f2c9e1b44b30b030a528f3
4
- data.tar.gz: c534a39e90383b0ac3896c8060d233dbd02c26c83563ed7d8c9d331b81c91370
3
+ metadata.gz: 6931a624fa28d354c72f47c02c06fe7041784c0a7f31668e66099d3fd3ee37e8
4
+ data.tar.gz: f9a71688a43c7fee6ba692cabd7f3b7903ebdd40388c762f0b643c6e80f0767e
5
5
  SHA512:
6
- metadata.gz: 95a11534001077454e72c94f94c81a2e816b613f9ab643ebaaeb06bbcf3e40f7210799130457d0af56677d2c0e5ac73ff8701426f778551c837f5b0ef9c3c711
7
- data.tar.gz: c0a4abe22639b9667cdfdf879f63a2c05e96c8ed3eac0d3376506b3d2e094724d5c18933ca9464ad099a87560545dbac91a55324ee82707f337d3eb2cf3a567c
6
+ metadata.gz: 25589fad75f1b12458b5b83273ffae665ab1cf4a31badeb1714d611f20e29de4a97567f06fe9472538021e95ca9bfd7dfbdf20665781c3a08fd3e60091dd54a5
7
+ data.tar.gz: ef0cfa5f786bc386f589d0fd9612a5165ae4051827a6b9b0e3e5561baee74da3cc9247eccfafed53610532436ea02795013c457e320da701aa295ffaed28f841
data/CHANGELOG CHANGED
@@ -1,10 +1,27 @@
1
+ 1.0.2
2
+
3
+ Simplify argv parsing code
4
+ Downcase websocket handshake headers
5
+ Add test case for invalid server requests
6
+ Update public np server address
7
+ Allow any base path in remote server URL
8
+ Stop on SIGTERM
9
+
10
+ 1.0.1
11
+
12
+ Simplify sequential and parallel request tests
13
+ Dump backtrace only if $VERBOSE is true
14
+ Manage $LOAD_PATH externally
15
+ Abort on unhandled exception
16
+
1
17
  1.0.0
2
18
 
3
- * Add backpressure mechanism to keep memory usage bounded
19
+ * Rename weblink to netpump
20
+ * Add direct client mode, where client connects to the server directly
21
+ * Add backpressure handling to keep memory usage low and bounded
4
22
  * Add websocket pool timeout
5
23
  * Add more unbind reasons
6
24
  * Add option to set the server URL, remove the server query param
7
- * Add direct client mode
8
25
 
9
26
  1.3.0
10
27
 
data/bin/netpump CHANGED
@@ -2,12 +2,7 @@
2
2
 
3
3
  Process.setproctitle "netpump"
4
4
  $stdin.close
5
- if $PROGRAM_NAME.include?("/")
6
- $VERBOSE = true
7
- $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
8
- else
9
- $VERBOSE = nil
10
- end
5
+ $VERBOSE = $PROGRAM_NAME == __FILE__ || nil
11
6
 
12
7
  require "optparse"
13
8
  require "uri"
@@ -17,8 +12,8 @@ copts = {}
17
12
  sopts = {}
18
13
 
19
14
  op = OptionParser.new do |op|
15
+ op.version = "1.0.2"
20
16
  op.summary_width = 24
21
-
22
17
  op.banner = "Usage: netpump [options]"
23
18
  op.separator ""
24
19
  op.separator "Options:"
@@ -39,15 +34,15 @@ op = OptionParser.new do |op|
39
34
  raise OptionParser::InvalidArgument, val
40
35
  end
41
36
 
42
- op.on("-c", "--client MODE", ["direct", "browser"], "start netpump client (mode: direct, browser)") do |mode|
37
+ op.on("-c", "--client MODE", ["direct", "browser"], "start np client (mode: direct, browser)") do |mode|
43
38
  copts[:mode] = mode
44
39
  end
45
40
 
46
- op.on("--client-host HOST", String, "client host (default: 0.0.0.0)") do |host|
41
+ op.on("--client-host HOST", String, "np client host (default: 0.0.0.0)") do |host|
47
42
  copts[:host] = host
48
43
  end
49
44
 
50
- op.on("--client-port PORT", Port, "client port (default: 8080)") do |port|
45
+ op.on("--client-port PORT", Port, "np client port (default: 8080)") do |port|
51
46
  copts[:port] = port
52
47
  end
53
48
 
@@ -59,32 +54,21 @@ op = OptionParser.new do |op|
59
54
  copts[:proxy_port] = port
60
55
  end
61
56
 
62
- op.on("--server-url URL", WSS, "netpump server url (example: wss://example.org)") do |url|
57
+ op.on("--server-url URL", WSS, "remote np server url (default: wss://s.netpump.org)") do |url|
63
58
  copts[:server_url] = url
64
59
  end
65
60
 
66
- op.on("-s", "--server", "start netpump server") do
61
+ op.on("-s", "--server", "start np server") do
67
62
  sopts[:server] = true
68
63
  end
69
64
 
70
- op.on("--server-host HOST", String, "server host (default: 0.0.0.0)") do |host|
65
+ op.on("--server-host HOST", String, "np server host (default: 0.0.0.0)") do |host|
71
66
  sopts[:host] = host
72
67
  end
73
68
 
74
- op.on("--server-port PORT", Port, "server port (default: 10000)") do |port|
69
+ op.on("--server-port PORT", Port, "np server port (default: 10000)") do |port|
75
70
  sopts[:port] = port
76
71
  end
77
-
78
- op.on_tail("--version", "print version") do
79
- version = File.expand_path("../VERSION", __dir__)
80
- puts(File.read(version))
81
- exit
82
- end
83
-
84
- op.on_tail("--help", "print this help") do
85
- puts(op)
86
- exit
87
- end
88
72
  end
89
73
 
90
74
  begin
@@ -97,9 +81,13 @@ else
97
81
  end
98
82
  end
99
83
 
100
- EventMachine.error_handler { |e| log "[!] unexpected errback.", error: e }
84
+ EventMachine.error_handler do |e|
85
+ log "[!] error: #{e.message}."
86
+ EventMachine.stop
87
+ end
101
88
  EventMachine.run do
102
89
  trap(:INT) { puts; EventMachine.stop }
90
+ trap(:TERM) { EventMachine.stop }
103
91
  if sopts.delete(:server)
104
92
  server = Netpump::Server.new(**sopts)
105
93
  server.start
@@ -108,7 +96,4 @@ EventMachine.run do
108
96
  client = Netpump::Client.new(**copts)
109
97
  client.start
110
98
  end
111
- rescue => e
112
- log "[!] #{e.message}."
113
- EventMachine.stop
114
99
  end
@@ -17,10 +17,14 @@ module EventMachine::WebSocket
17
17
  @parser.on_headers_complete = proc do
18
18
  headers = @parser.headers
19
19
  @parser = nil
20
- accept = Digest::SHA1.base64digest(@key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
21
- unless headers["Connection"]&.downcase == "upgrade" &&
22
- headers["Upgrade"]&.downcase == "websocket" &&
23
- headers["Sec-WebSocket-Accept"] == accept
20
+ headers.transform_keys!(&:downcase)
21
+ con = headers["connection"]
22
+ con&.downcase!
23
+ upg = headers["upgrade"]
24
+ upg&.downcase!
25
+ acc = headers["sec-websocket-accept"]
26
+ acc_ = Digest::SHA1.base64digest(@key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
27
+ unless con == "upgrade" && upg == "websocket" && acc == acc_
24
28
  raise HandshakeError, "Invalid server handshake"
25
29
  end
26
30
  debug [:handshake_completed]
@@ -34,7 +34,7 @@ module EventMachine::WebSocket::Server
34
34
 
35
35
  def ws.serve_file(path)
36
36
  send_data("HTTP/1.1 200 OK\r\n\r\n")
37
- # win: send/stream_file_data do not work on windows
37
+ # windows: send/stream_file_data do not work
38
38
  send_data(path.read)
39
39
  close_connection_after_writing
40
40
  end
@@ -15,14 +15,19 @@ module Netpump
15
15
  port: "8080",
16
16
  proxy_host: "127.0.0.1",
17
17
  proxy_port: 3128,
18
- server_url: "wss://weblink-ouux.onrender.com",
18
+ server_url: "wss://s.netpump.org",
19
19
  connection_inactivity_timeout: 30.0,
20
20
  websocket_pool_size: 20,
21
21
  websocket_pool_timeout: 60.0
22
22
  )
23
23
  @mode = mode
24
- @host = host
25
- @port = port
24
+ if mode == "browser"
25
+ @host = host
26
+ @port = port
27
+ else
28
+ @host = nil
29
+ @port = nil
30
+ end
26
31
  @proxy_host = proxy_host
27
32
  @proxy_port = proxy_port
28
33
  @server_url = URI(server_url)
@@ -31,12 +36,14 @@ module Netpump
31
36
  @websocket_pool_size = websocket_pool_size
32
37
  @websocket_pool_timeout = websocket_pool_timeout
33
38
  @control_ws = nil
34
- @log = lambda { |msg, **ctx| log(msg, loc: true, **ctx) }
39
+ @log = lambda { |msg, **ctx| log(msg, c: true, **ctx) }
35
40
  @ready = EventMachine::Completion.new
41
+ @ready.callback do
42
+ @log.call "[+] np client is ready.", mode: @mode, host: @host, port: @port
43
+ end
36
44
  end
37
45
 
38
46
  def start
39
- @log.call "[+] netpump client is starting.", mode: @mode, host: @host, port: @port
40
47
  case @mode
41
48
  when "direct"
42
49
  start_proxy_server
@@ -58,10 +65,10 @@ module Netpump
58
65
  case path
59
66
  when "/"
60
67
  ws.serve_file(PUBLIC_DIR.join("netpump.html"))
61
- @log.call "[~] http request.", method: "GET", path: path, ip: ws.remote_ip
68
+ @log.call "[~] http request.", ip: ws.remote_ip, method: "GET", path: path
62
69
  when "/favicon.svg"
63
70
  ws.serve_file(PUBLIC_DIR.join("favicon.svg"))
64
- @log.call "[~] http request.", method: "GET", path: path, ip: ws.remote_ip
71
+ @log.call "[~] http request.", ip: ws.remote_ip, method: "GET", path: path
65
72
  when "/ws/loc/control"
66
73
  next false if @control_ws
67
74
  ws.onopen do |_handshake|
@@ -73,7 +80,7 @@ module Netpump
73
80
  @control_ws = nil
74
81
  @log.call "[-] device is disconnected.", sig: ws.signature
75
82
  EventMachine.stop_server(proxy)
76
- @log.call "[-] proxy server is stopped."
83
+ @log.call "[-] np proxy server is stopped."
77
84
  end
78
85
  @ready.succeed
79
86
  end
@@ -100,10 +107,10 @@ module Netpump
100
107
  end
101
108
 
102
109
  def start_proxy_server
103
- proxy = EventMachine.start_server(@proxy_host, @proxy_port, Relay, "loc") do |relay|
110
+ proxy = EventMachine.start_server(@proxy_host, @proxy_port, Relay, "c") do |relay|
104
111
  bind(relay)
105
112
  end
106
- @log.call "[+] proxy server is ready.", type: "https", host: @proxy_host, port: @proxy_port
113
+ @log.call "[+] np proxy server is ready.", type: "https", host: @proxy_host, port: @proxy_port
107
114
  proxy
108
115
  end
109
116
 
data/lib/netpump/log.rb CHANGED
@@ -7,7 +7,7 @@ def log(msg, **context)
7
7
  case v
8
8
  when Exception
9
9
  line << " #{k}=#{v.message.inspect}"
10
- line << " backtrace=#{v.backtrace}" if !$VERBOSE.nil? && v.backtrace
10
+ line << " backtrace=#{v.backtrace}" if $VERBOSE && v.backtrace
11
11
  when true
12
12
  line << " #{k}"
13
13
  when false, nil, ""
data/lib/netpump/relay.rb CHANGED
@@ -34,10 +34,11 @@ module Netpump
34
34
  @remote_ip = remote_ip
35
35
  @connection_inactivity_timeout = comm_inactivity_timeout
36
36
  if @closed
37
- # If a connection is closed due to the pool timeout before being bound to
38
- # a websocket, it is not added to the wait queue in the websocket pool,
39
- # so this case should not happen under normal operation. However, it is
40
- # still possible is the connection is closed due to any other reason.
37
+ # If a connection is closed due to the pool timeout before being bound
38
+ # to a websocket, it is not added to the wait queue in the websocket
39
+ # pool, so this case should not happen under normal operation. However,
40
+ # it is still possible if the connection is closed due to any other
41
+ # reason.
41
42
  @log.call "[!] bound closed before bind."
42
43
  @completion.succeed
43
44
  return @completion
@@ -97,7 +98,7 @@ module Netpump
97
98
  reason = errno.exception.message
98
99
  reason[0] = reason[0].downcase
99
100
  else
100
- # win: errno can be set to :unknown on windows
101
+ # windows: errno can be set to :unknown
101
102
  reason = errno.to_s
102
103
  end
103
104
  @log.call "[-] unbind.", reason: reason
@@ -11,11 +11,10 @@ module Netpump
11
11
  @port = port
12
12
  @proxy_host = proxy_host
13
13
  @proxy_port = proxy_port
14
- @log = lambda { |msg, **ctx| log(msg, rem: true, **ctx) }
14
+ @log = lambda { |msg, **ctx| log(msg, s: true, **ctx) }
15
15
  end
16
16
 
17
17
  def start
18
- @log.call "[+] netpump server is starting.", host: @host, port: @port
19
18
  start_websocket_server
20
19
  proxy = EventMachine.start_server(
21
20
  @proxy_host, @proxy_port, EventMachine::Protocols::CONNECT
@@ -23,6 +22,7 @@ module Netpump
23
22
  fail "inactivity timeout" unless c.comm_inactivity_timeout.zero?
24
23
  end
25
24
  @proxy_port, @proxy_host = Socket.unpack_sockaddr_in(EventMachine.get_sockname(proxy))
25
+ @log.call "[+] np server is ready.", host: @host, port: @port
26
26
  end
27
27
 
28
28
  private
@@ -41,14 +41,14 @@ module Netpump
41
41
  bind(ws, ip)
42
42
  end
43
43
  else
44
- return false
44
+ next false
45
45
  end
46
46
  true
47
47
  end
48
48
  end
49
49
 
50
50
  def bind(ws, ip)
51
- EventMachine.connect(@proxy_host, @proxy_port, Relay, "rem") do |relay|
51
+ EventMachine.connect(@proxy_host, @proxy_port, Relay, "s") do |relay|
52
52
  fail "inactivity timeout" unless relay.comm_inactivity_timeout.zero?
53
53
  relay.bind(ws, ip).callback { bind(ws, ip) }
54
54
  end
data/public/netpump.html CHANGED
@@ -20,12 +20,6 @@
20
20
  text-align: center;
21
21
  color: white;
22
22
  }
23
- dd {
24
- margin: 0;
25
- }
26
- input[type="checkbox"] {
27
- margin-right: 0.5em;
28
- }
29
23
  header {
30
24
  margin: 1em 0;
31
25
  }
@@ -36,6 +30,12 @@
36
30
  header svg {
37
31
  width: 4em;
38
32
  }
33
+ dd {
34
+ margin: 0;
35
+ }
36
+ input[type="checkbox"] {
37
+ margin-right: 0.5em;
38
+ }
39
39
  </style>
40
40
  </head>
41
41
  <body>
@@ -63,8 +63,8 @@
63
63
  // client websocket.
64
64
  var client;
65
65
  // Connect to the server first, so that when we
66
- // connect to the client the whole chain is complete.
67
- var server = new WebSocket(serverAddr + "/ws/rem/relay");
66
+ // connect to the client, the whole chain is complete.
67
+ var server = new WebSocket(new URL("/ws/rem/relay", serverAddr));
68
68
  // Log server errors.
69
69
  server.onerror = function (event) {
70
70
  console.error("[!] server/error", event);
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: netpump
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - soylent
@@ -9,6 +9,20 @@ bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: base64
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '0.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '0.0'
12
26
  - !ruby/object:Gem::Dependency
13
27
  name: em-websocket
14
28
  requirement: !ruby/object:Gem::Requirement
@@ -43,7 +57,6 @@ extensions: []
43
57
  extra_rdoc_files: []
44
58
  files:
45
59
  - CHANGELOG
46
- - VERSION
47
60
  - bin/netpump
48
61
  - lib/eventmachine/websocket/client.rb
49
62
  - lib/eventmachine/websocket/server.rb
@@ -74,5 +87,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
87
  requirements: []
75
88
  rubygems_version: 3.6.9
76
89
  specification_version: 4
77
- summary: Tiny websocket proxy tunnel
90
+ summary: tiny websocket proxy tunnel
78
91
  test_files: []
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 1.0.0