weblink 1.0.0 → 1.1.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: 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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
- FgYDVQQDDA9lZmlyL0RDPXNveWxlbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
16
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- SIb3DQEBCwUAA4IBAQBsJ7htnm3RB5xQwzC2agRAgG2ax5uaD6lCEPWshGJbfT6v
25
- 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
- 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
- 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
- VIAqJBK/gwFlRxVYjmi2w4Ouc4wL8HtX104yQqOuD9gVPN6PJecue66As7i2I/2q
29
- EARmnubhy24GUdxEooHV6pOs1mLLRuFepMgBnHfs
13
+ MIIEDjCCAvagAwIBAgIBATANBgkqhkiG9w0BAQsFADB3MRgwFgYDVQQDDA8xNTkz
14
+ ODYwX3NveWxlbnQxFTATBgoJkiaJk/IsZAEZFgV1c2VyczEXMBUGCgmSJomT8ixk
15
+ ARkWB25vcmVwbHkxFjAUBgoJkiaJk/IsZAEZFgZnaXRodWIxEzARBgoJkiaJk/Is
16
+ ZAEZFgNjb20wHhcNMjIwMTI3MDIzMTQwWhcNMjMwMTI3MDIzMTQwWjB3MRgwFgYD
17
+ VQQDDA8xNTkzODYwX3NveWxlbnQxFTATBgoJkiaJk/IsZAEZFgV1c2VyczEXMBUG
18
+ CgmSJomT8ixkARkWB25vcmVwbHkxFjAUBgoJkiaJk/IsZAEZFgZnaXRodWIxEzAR
19
+ BgoJkiaJk/IsZAEZFgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
20
+ AQC2DMbzgA39U+3VTMjXn+0jnOQyLdmXQ5EXgSLKCgBLIcFTc9J47Th07Yb/f4Rz
21
+ Wh49/EkDBiDtLqFeKBYsj3q0e8tRCAs32NtVyl/4FDyJvWsK3R2tcXOVqxs48J3C
22
+ gG+rFLOcMC9YF4FPTkz4p3EYGFVjZTbiqyVVuIZzWtrwdZesBVgpBRyN8sEyNoi8
23
+ vcDiOmEwf9/TVMTDf/wu6a+i3LNVGYWlvgMJRssaAnj/IbFFtPTz30HxeTUdfJu8
24
+ YbwRspfFzcJGLf32E7vXfmHHqNzqjh4zD9sVpvTHbqLLsgVa+nYHPHAedzSZ5gZj
25
+ G1oZ7hZDCJoEPj0oCHT0qkuXAgMBAAGjgaQwgaEwCQYDVR0TBAIwADALBgNVHQ8E
26
+ BAMCBLAwHQYDVR0OBBYEFKy+nUcB8D5BOM6D96HKG/tp2nQWMDMGA1UdEQQsMCqB
27
+ KDE1OTM4NjArc295bGVudEB1c2Vycy5ub3JlcGx5LmdpdGh1Yi5jb20wMwYDVR0S
28
+ BCwwKoEoMTU5Mzg2MCtzb3lsZW50QHVzZXJzLm5vcmVwbHkuZ2l0aHViLmNvbTAN
29
+ BgkqhkiG9w0BAQsFAAOCAQEAsfJgulszbe+BgUP9xNYixuvm/R8Um5T8OAANmc+s
30
+ CvV3lD5XtFuw838TbWrqgN+7dVkzQYERTz8DjPtx+zlgzNS3GyMWNUZdOPLo/YkR
31
+ S7KfmAZlZhy1rcrARYsAouvP+1QttbiJ32L+z1JzAz2s1+4ySgl1OaQfosS04QGT
32
+ CnJ982/OGeG5xm7KFOqSzG4KnyEy4VH47aE4IQk+yP6R96neHdfOd/C7BcA6gbgH
33
+ lyshHS0Bgr1OKk3Vx8GtaIa7L9Z4RN0EWBL3QGlhiu55PrpPuAFDDuORJfpIqrph
34
+ XjC/3xZEDxBLYSjeFIgUMN6+/XGduQANkZ6167QsVu/yPg==
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