weblink 1.0.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c268c95b2cdcec3669dbf5c90f0753bc28949b6098744bd7c9f9e42aac24bb97
4
- data.tar.gz: 44f0363bf19eae1f40a5a00fd962f60134a1db2a12e36aeda7bba04fe5090855
3
+ metadata.gz: 13496b146b017e1d415d1fb4ee27b36deb894f158882dc376490be51a6920184
4
+ data.tar.gz: cf4643c4a79bb42f8f2b79e05197915e866d90d54be68689aa3df628f237385e
5
5
  SHA512:
6
- metadata.gz: 72ba709dd3bbdc06582bb20a83ab50090d8a60859698f4a00576122b0cd9687ed348b24d4ddbadc99219011750b897e4596605369c46e75655a821c7a76c4716
7
- data.tar.gz: d729d225e330f6ab9714bd078893eeeecccb5d56e85f0f5d39c92f4b192a4fd9f94243789b94e0008b6264906d6a33c50f59682cb5afb215b0f21aa649202515
6
+ metadata.gz: 11b4b83e40f513ef9b4cbeb3ae532dc5c794da491e0adc06b69fa9c3736c80148998d26c1cf0eef78ff1cced9bfea691806bfebf7fb1bbd6ec720f453936d695
7
+ data.tar.gz: d2083018ee29d25126c5379524bd59af249e55ac8b3b5030517b7ba905a2d122a5851a9fcb43611b215799acaeefbed3a88e4163946ef68c8426b01d2ff9ed8b
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG CHANGED
@@ -1,3 +1,17 @@
1
+ 1.1.2
2
+
3
+ * Add webrick as a runtime dependency
4
+
5
+ 1.1.1
6
+
7
+ * Ignore interfaces with nil addresses
8
+
9
+ 1.1.0
10
+
11
+ * Works on Windows
12
+ * HTTPS proxy support
13
+
1
14
  1.0.0
2
15
 
3
16
  * First public release
17
+ * SOCKS5 proxy support
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.1.2
data/bin/weblink CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env -S ruby -w
2
- # frozen_string_literal: true
3
2
 
4
3
  $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
5
4
 
@@ -35,11 +34,16 @@ op = OptionParser.new do |op|
35
34
  opts[:port] = port
36
35
  end
37
36
 
37
+ op.on('--proxy-type TYPE', String, 'https or socks5 (default: https)') do |type|
38
+ raise OptionParser::InvalidArgument, type unless type == 'https' || type == 'socks5'
39
+ opts[:proxy_type] = type
40
+ end
41
+
38
42
  op.on('--proxy-host HOST', String, 'Address to bind proxy to(default: 0.0.0.0)') do |host|
39
43
  opts[:proxy_host] = host
40
44
  end
41
45
 
42
- op.on('--proxy-port PORT', Integer, 'Use proxy PORT (default: 1080)') do |port|
46
+ op.on('--proxy-port PORT', Integer, 'Use proxy PORT (default: 3128)') do |port|
43
47
  opts[:proxy_port] = port
44
48
  end
45
49
 
@@ -66,8 +70,9 @@ else
66
70
  end
67
71
  opts[:host] ||= '0.0.0.0'
68
72
  opts[:port] ||= 8000
73
+ opts[:proxy_type] ||= 'https'
69
74
  opts[:proxy_host] ||= '0.0.0.0'
70
- opts[:proxy_port] ||= 1080
75
+ opts[:proxy_port] ||= 3128
71
76
  end
72
77
 
73
78
  weblink = Weblink.new(opts)
data/lib/relay.rb CHANGED
@@ -3,6 +3,7 @@ require 'time'
3
3
 
4
4
  class Relay < EventMachine::Connection
5
5
  def initialize(tag, xff = nil)
6
+ super
6
7
  pause
7
8
  @tag = tag
8
9
  @xff = xff
@@ -31,6 +32,7 @@ class Relay < EventMachine::Connection
31
32
 
32
33
  def unbind
33
34
  log('close')
35
+ # Status code 1000 indicates indicates a normal closure.
34
36
  @websocket&.close(1000) if @websocket&.state == :connected
35
37
  end
36
38
 
data/lib/weblink.rb CHANGED
@@ -7,7 +7,8 @@ require 'relay'
7
7
  class Weblink
8
8
  def initialize(opts)
9
9
  @opts = opts
10
- @proxxxy_socket = Tempfile.new('weblink')
10
+ @https = Tempfile.new('weblink')
11
+ @socks5 = Tempfile.new('weblink')
11
12
  @websockets = EventMachine::Queue.new
12
13
  end
13
14
 
@@ -15,16 +16,22 @@ class Weblink
15
16
  trap(:EXIT) { Process.waitall }
16
17
 
17
18
  if @opts[:client]
18
- public = File.expand_path('../public', __dir__)
19
- spawn('ruby', '-run', '-ehttpd', '--', public, err: '/dev/null')
20
-
21
- ip = Socket.getifaddrs.find { |ifa| ifa.addr.ipv4_private? }
22
- puts "Open http://#{ip.addr.ip_address}:8080/ on your other device." if ip
19
+ ip = Socket.getifaddrs.find { |ifa| ifa.addr&.ipv4_private? }
20
+ if ip
21
+ public = File.expand_path('../public', __dir__)
22
+ spawn('ruby', '-run', '-ehttpd', '--', public, err: IO::NULL)
23
+ puts "Open http://#{ip.addr.ip_address}:8080/ on your other device."
24
+ else
25
+ abort(
26
+ "Could not find an interface to listen on. " \
27
+ "Make sure that you are connected to your device."
28
+ )
29
+ end
23
30
  end
24
31
 
25
32
  if @opts[:server]
26
33
  begin
27
- spawn('proxxxy', "socks5://#{@proxxxy_socket.path}")
34
+ spawn('proxxxy', "https://#{@https.path}", "socks5://#{@socks5.path}")
28
35
  rescue Errno::ENOENT
29
36
  abort('Please install proxxxy v2 to run weblink server')
30
37
  end
@@ -38,8 +45,10 @@ class Weblink
38
45
  puts 'Ready'
39
46
  when '/client'
40
47
  @websockets.push(ws)
41
- when '/server'
42
- proxy(ws, handshake)
48
+ when '/proxy/socks5'
49
+ proxy(ws, handshake, @socks5.path)
50
+ when '/proxy/https'
51
+ proxy(ws, handshake, @https.path)
43
52
  else
44
53
  warn("Unexpected request: #{handshake.path.inspect}")
45
54
  end
@@ -53,26 +62,26 @@ class Weblink
53
62
  host, port = @opts.values_at(:proxy_host, :proxy_port)
54
63
  sig = EventMachine.start_server(host, port, Relay, 'client') do |rel|
55
64
  # Dogpile effect
56
- control_ws.send_text('more_ws') if @websockets.size < min_ws_num
65
+ control_ws.send_text(@opts[:proxy_type]) if @websockets.size < min_ws_num
57
66
  @websockets.pop { |ws| rel.start(ws) }
58
67
  end
59
68
  control_ws.onclose { EventMachine.stop_server(sig) }
60
69
  end
61
70
 
62
- def proxy(ws, handshake)
71
+ def proxy(ws, handshake, socket)
63
72
  unless @opts[:server]
64
73
  warn 'weblink server is disabled'
65
74
  return
66
75
  end
67
76
  xff = handshake.headers_downcased['x-forwarded-for']
68
- with_retry(3) do
69
- EventMachine.connect(@proxxxy_socket.path, Relay, 'server', xff) do |rel|
77
+ with_retry(timeout: 3) do
78
+ EventMachine.connect(socket, Relay, 'server', xff) do |rel|
70
79
  rel.start(ws)
71
80
  end
72
81
  end
73
82
  end
74
83
 
75
- def with_retry(timeout, wait: 0.1)
84
+ def with_retry(timeout:, wait: 0.1)
76
85
  elapsed = 0
77
86
  begin
78
87
  yield
data/public/index.html CHANGED
@@ -1,67 +1,73 @@
1
+ <!DOCTYPE html>
1
2
  <html>
2
3
  <head>
3
4
  <meta charset="utf-8" />
4
5
  <title>weblink</title>
5
6
  <link rel="manifest" href="/weblink.webmanifest">
6
7
  <style>
8
+ html, body {
9
+ height: 100%;
10
+ }
7
11
  body {
12
+ align-items: center;
8
13
  background-color: #3f9cff;
9
14
  color: white;
15
+ display: flex;
16
+ justify-content: center;
10
17
  }
11
18
  h1 {
12
- align-items: center;
13
- display: flex;
14
19
  font-family: sans-serif;
15
20
  font-size: 8em;
16
- justify-content: center;
17
- height: 100%;
18
21
  }
19
22
  </style>
20
23
  </head>
21
24
  <body>
22
25
  <h1>weblink</h1>
23
26
  <script>
24
- function connect({ client_addr, server_addr }) {
25
- const client = new WebSocket(client_addr + "/client");
26
- const server = new WebSocket(server_addr + "/server");
27
+ function connect(client_addr, server_addr, proxy) {
28
+ var client, server = new WebSocket(server_addr + "/proxy/" + proxy);
27
29
 
28
30
  server.onerror = function(event) { console.error("server/error"); };
29
- client.onerror = function(event) { console.error("client/error"); };
30
31
 
31
- client.onopen = function() {
32
- server.onopen = function() {
32
+ server.onopen = function() {
33
+ client = new WebSocket(client_addr + "/client");
34
+
35
+ client.onerror = function(event) { console.error("client/error"); };
36
+
37
+ client.onopen = function() {
33
38
  client.onmessage = function(msg) { server.send(msg.data); };
34
39
  server.onmessage = function(msg) { client.send(msg.data); };
35
40
  };
41
+
42
+ client.onclose = function(event) {
43
+ console.log("client/close", event.code, event.reason);
44
+ if (server.readyState === WebSocket.OPEN) server.close();
45
+ };
36
46
  };
37
47
 
38
48
  server.onclose = function(event) {
39
49
  console.log("server/close", event.code, event.reason);
40
-
41
50
  if (client.readyState === WebSocket.OPEN) client.close();
42
51
  };
43
-
44
- client.onclose = function(event) {
45
- console.log("client/close", event.code, event.reason);
46
-
47
- if (server.readyState === WebSocket.OPEN) server.close();
48
- };
49
52
  }
50
53
 
51
- const url = new URL(location.href);
52
- const client_addr = `ws://${location.hostname}:8000`;
53
- const server_addr = url.searchParams.get("server") || "wss://weblinkapp.herokuapp.com";
54
- const batch_size = Number(url.searchParams.get("batch")) || 4
55
- const control = new WebSocket(client_addr + "/control");
54
+ var params = {};
55
+ window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/g, function(m, key, value) {
56
+ params[key] = decodeURIComponent(value);
57
+ });
58
+
59
+ var client_addr = "ws://" + location.hostname + ":8000";
60
+ var server_addr = params.server || "wss://weblinkapp.herokuapp.com";
61
+ var batch_size = Number(params.batch) || 4;
62
+ var control = new WebSocket(client_addr + "/control");
56
63
 
57
64
  control.onerror = function(event) { console.error("control/error"); };
58
65
  control.onclose = function(event) { console.log("control/close"); };
59
66
  control.onmessage = function(msg) {
60
67
  for (var i = 0; i < batch_size; i++) {
61
- connect({ client_addr, server_addr });
68
+ connect(client_addr, server_addr, msg.data);
62
69
  }
63
70
  };
64
- control.onmessage();
65
71
  </script>
66
72
  </body>
67
73
  </html>
data/public/weblink.js ADDED
@@ -0,0 +1,59 @@
1
+ function connect(client_addr, server_addr) {
2
+ var client = new WebSocket(client_addr + "/client");
3
+ var server = new WebSocket(server_addr + "/server");
4
+
5
+ server.onerror = function(event) {
6
+ console.error("server/error");
7
+ };
8
+ client.onerror = function(event) {
9
+ console.error("client/error");
10
+ };
11
+
12
+ client.onopen = function() {
13
+ server.onopen = function() {
14
+ client.onmessage = function(msg) {
15
+ server.send(msg.data);
16
+ };
17
+ server.onmessage = function(msg) {
18
+ client.send(msg.data);
19
+ };
20
+ };
21
+ };
22
+
23
+ server.onclose = function(event) {
24
+ console.log("server/close", event.code, event.reason);
25
+
26
+ if (client.readyState === WebSocket.OPEN) client.close();
27
+ };
28
+
29
+ client.onclose = function(event) {
30
+ console.log("client/close", event.code, event.reason);
31
+
32
+ if (server.readyState === WebSocket.OPEN) server.close();
33
+ };
34
+ }
35
+
36
+ var params = {};
37
+ window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/g, function(m, key, value) {
38
+ params[key] = value;
39
+ });
40
+
41
+ var client_addr = "ws://" + location.hostname + ":8000";
42
+ var server_addr = params.server || "wss://weblinkapp.herokuapp.com";
43
+ var batch_size = Number(params.batch) || 4;
44
+ var control = new WebSocket(client_addr + "/control");
45
+
46
+ control.onerror = function(event) {
47
+ console.error("control/error");
48
+ };
49
+ control.onclose = function(event) {
50
+ console.log("control/close");
51
+ };
52
+ control.onmessage = function(msg) {
53
+ for (var i = 0; i < batch_size; i++)
54
+ connect(
55
+ client_addr,
56
+ server_addr
57
+ );
58
+ };
59
+ control.onmessage();
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: weblink
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - soylent
@@ -10,25 +10,30 @@ bindir: bin
10
10
  cert_chain:
11
11
  - |
12
12
  -----BEGIN CERTIFICATE-----
13
- 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
- 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
- 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
- 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
- 7Yb/f4RzWh49/EkDBiDtLqFeKBYsj3q0e8tRCAs32NtVyl/4FDyJvWsK3R2tcXOV
18
- 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
- 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
- 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
- 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
- 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
- EDAOgQxlZmlyQHNveWxlbnQwFwYDVR0SBBAwDoEMZWZpckBzb3lsZW50MA0GCSqG
24
- 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
- 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
- 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
- 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
- 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
- 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
30
35
  -----END CERTIFICATE-----
31
- date: 2020-12-23 00:00:00.000000000 Z
36
+ date: 2022-03-05 00:00:00.000000000 Z
32
37
  dependencies:
33
38
  - !ruby/object:Gem::Dependency
34
39
  name: em-websocket
@@ -44,6 +49,20 @@ dependencies:
44
49
  - - "~>"
45
50
  - !ruby/object:Gem::Version
46
51
  version: '0.5'
52
+ - !ruby/object:Gem::Dependency
53
+ name: webrick
54
+ requirement: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - "~>"
57
+ - !ruby/object:Gem::Version
58
+ version: '1.7'
59
+ type: :runtime
60
+ prerelease: false
61
+ version_requirements: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - "~>"
64
+ - !ruby/object:Gem::Version
65
+ version: '1.7'
47
66
  description:
48
67
  email:
49
68
  executables:
@@ -63,6 +82,7 @@ files:
63
82
  - public/favicon-32x32.png
64
83
  - public/favicon.ico
65
84
  - public/index.html
85
+ - public/weblink.js
66
86
  - public/weblink.webmanifest
67
87
  homepage: https://github.com/soylent/weblink
68
88
  licenses: []
@@ -82,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
102
  - !ruby/object:Gem::Version
83
103
  version: '0'
84
104
  requirements: []
85
- rubygems_version: 3.1.4
105
+ rubygems_version: 3.3.4
86
106
  signing_key:
87
107
  specification_version: 4
88
108
  summary: Web browser gateway
metadata.gz.sig CHANGED
Binary file