forward-proxy 0.5.0 → 0.7.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 +4 -4
- data/.github/workflows/ci.yaml +1 -1
- data/.github/workflows/cli.yaml +1 -1
- data/CHANGELOG.md +10 -0
- data/README.md +2 -1
- data/exe/forward-proxy +6 -1
- data/lib/forward_proxy/errors/connection_timeout_error.rb +5 -0
- data/lib/forward_proxy/server.rb +28 -17
- data/lib/forward_proxy/thread_pool.rb +9 -4
- data/lib/forward_proxy/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3018291ebebbfa87a02ba1409fa3f0c0af9b5d0ffb8917636dd4f8e397d8a4fb
|
4
|
+
data.tar.gz: dd3420d19ee1ac89064d7fd965768072cc25ce100555a4dc59881530fc2b6d66
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz: '
|
6
|
+
metadata.gz: c1676662f33627745b09c2049957a4232885862bac77ba4f1ecb48b085683ef832825d2a0b15c725bdf6553456bb710c1b847f4027e55e8ed31c1c31aa1b307f
|
7
|
+
data.tar.gz: '08652da6a675acfb0c371d571bad140d3a50673d76d2aae74ea6a33f2b4f1e21b07f3378fcaaf74099d6fe93de29cc923108c1d278a9364b885b80a405951643'
|
data/.github/workflows/ci.yaml
CHANGED
data/.github/workflows/cli.yaml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 0.6.0
|
4
|
+
|
5
|
+
- add connection timeout to stop tracking connection from saturating client threads.
|
6
|
+
- add cli flats for connection timeout `-t` and `--timeout`.
|
7
|
+
- change cli short flag `-t` to `-c` for `--threads`.
|
8
|
+
|
9
|
+
## 0.5.0
|
10
|
+
|
11
|
+
- increase default threads from `32` to `128`.
|
12
|
+
|
3
13
|
## 0.2.0
|
4
14
|
|
5
15
|
- Extract errors into module.
|
data/README.md
CHANGED
@@ -38,7 +38,8 @@ forward-proxy
|
|
38
38
|
Usage: forward-proxy [options]
|
39
39
|
-p, --port=PORT Bind to specified port. Default: 9292
|
40
40
|
-b, --binding=BINDING Bind to the specified ip. Default: 127.0.0.1
|
41
|
-
-t, --
|
41
|
+
-t, --timeout=TIMEOUT Specify the connection timeout in seconds. Default: 300
|
42
|
+
-c, --threads=THREADS Specify the number of client threads. Default: 128
|
42
43
|
-h, --help Prints this help.
|
43
44
|
```
|
44
45
|
|
data/exe/forward-proxy
CHANGED
@@ -15,7 +15,12 @@ OptionParser.new do |parser|
|
|
15
15
|
options[:bind_address] = bind_address
|
16
16
|
end
|
17
17
|
|
18
|
-
parser.on("-
|
18
|
+
parser.on("-tTIMEOUT", "--timeout=TIMEOUT", Integer,
|
19
|
+
"Specify the connection timeout in seconds. Default: 300") do |threads|
|
20
|
+
options[:timeout] = threads
|
21
|
+
end
|
22
|
+
|
23
|
+
parser.on("-cTHREADS", "--threads=THREADS", Integer,
|
19
24
|
"Specify the number of client threads. Default: 128") do |threads|
|
20
25
|
options[:threads] = threads
|
21
26
|
end
|
data/lib/forward_proxy/server.rb
CHANGED
@@ -1,20 +1,23 @@
|
|
1
1
|
require 'logger'
|
2
2
|
require 'socket'
|
3
|
-
require '
|
3
|
+
require 'timeout'
|
4
4
|
require 'net/http'
|
5
|
+
require 'webrick'
|
6
|
+
require 'forward_proxy/errors/connection_timeout_error'
|
5
7
|
require 'forward_proxy/errors/http_method_not_implemented'
|
6
8
|
require 'forward_proxy/errors/http_parse_error'
|
7
9
|
require 'forward_proxy/thread_pool'
|
8
10
|
|
9
11
|
module ForwardProxy
|
10
12
|
class Server
|
11
|
-
attr_reader :bind_address, :bind_port, :logger
|
13
|
+
attr_reader :bind_address, :bind_port, :logger, :timeout
|
12
14
|
|
13
|
-
def initialize(bind_address: "127.0.0.1", bind_port: 9292, threads: 128, logger: default_logger)
|
15
|
+
def initialize(bind_address: "127.0.0.1", bind_port: 9292, threads: 128, timeout: 300, logger: default_logger)
|
14
16
|
@bind_address = bind_address
|
15
17
|
@bind_port = bind_port
|
16
18
|
@logger = logger
|
17
19
|
@thread_pool = ThreadPool.new(threads)
|
20
|
+
@timeout = timeout
|
18
21
|
end
|
19
22
|
|
20
23
|
def start
|
@@ -27,18 +30,20 @@ module ForwardProxy
|
|
27
30
|
loop do
|
28
31
|
thread_pool.schedule(socket.accept) do |client_conn|
|
29
32
|
begin
|
30
|
-
|
33
|
+
Timeout::timeout(timeout, Errors::ConnectionTimeoutError, "connection exceeded #{timeout} seconds") do
|
34
|
+
req = parse_req(client_conn)
|
31
35
|
|
32
|
-
|
36
|
+
logger.info(req.request_line.strip)
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
case req.request_method
|
39
|
+
when METHOD_CONNECT then handle_tunnel(client_conn, req)
|
40
|
+
when METHOD_GET, METHOD_POST then handle(client_conn, req)
|
41
|
+
else
|
42
|
+
raise Errors::HTTPMethodNotImplemented
|
43
|
+
end
|
39
44
|
end
|
40
45
|
rescue => e
|
41
|
-
handle_error(
|
46
|
+
handle_error(client_conn, e)
|
42
47
|
ensure
|
43
48
|
client_conn.close
|
44
49
|
end
|
@@ -62,14 +67,14 @@ module ForwardProxy
|
|
62
67
|
|
63
68
|
attr_reader :socket, :thread_pool
|
64
69
|
|
65
|
-
# The following comments are from the IETF document
|
66
|
-
# "Hypertext Transfer Protocol -- HTTP/1.1: Basic Rules"
|
67
|
-
# https://datatracker.ietf.org/doc/html/rfc2616#section-2.2
|
68
|
-
|
69
70
|
METHOD_CONNECT = "CONNECT"
|
70
71
|
METHOD_GET = "GET"
|
71
72
|
METHOD_POST = "POST"
|
72
73
|
|
74
|
+
# The following comments are from the IETF document
|
75
|
+
# "Hypertext Transfer Protocol -- HTTP/1.1: Basic Rules"
|
76
|
+
# https://datatracker.ietf.org/doc/html/rfc2616#section-2.2
|
77
|
+
|
73
78
|
# HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all
|
74
79
|
# protocol elements except the entity-body.
|
75
80
|
HEADER_EOP = "\r\n"
|
@@ -165,9 +170,15 @@ module ForwardProxy
|
|
165
170
|
end
|
166
171
|
end
|
167
172
|
|
168
|
-
def handle_error(
|
173
|
+
def handle_error(client_conn, err)
|
174
|
+
status_code = case err
|
175
|
+
when Errors::ConnectionTimeoutError then 504
|
176
|
+
else
|
177
|
+
502
|
178
|
+
end
|
179
|
+
|
169
180
|
client_conn.puts <<~eos.chomp
|
170
|
-
HTTP/1.1
|
181
|
+
HTTP/1.1 #{status_code}
|
171
182
|
Via: #{HEADER_VIA}
|
172
183
|
#{HEADER_EOP}
|
173
184
|
eos
|
@@ -1,24 +1,29 @@
|
|
1
1
|
module ForwardProxy
|
2
2
|
class ThreadPool
|
3
|
-
attr_reader :queue, :size
|
3
|
+
attr_reader :queue, :size, :threads
|
4
4
|
|
5
5
|
def initialize(size)
|
6
|
-
@
|
7
|
-
@
|
6
|
+
@queue = Queue.new
|
7
|
+
@size = size
|
8
|
+
@threads = []
|
8
9
|
end
|
9
10
|
|
10
11
|
def start
|
11
12
|
size.times do
|
12
|
-
Thread.new do
|
13
|
+
thread = Thread.new do
|
13
14
|
loop do
|
14
15
|
job, args = queue.pop
|
15
16
|
job.call(*args)
|
16
17
|
end
|
17
18
|
end
|
19
|
+
|
20
|
+
threads.push(thread)
|
18
21
|
end
|
19
22
|
end
|
20
23
|
|
21
24
|
def schedule(*args, &block)
|
25
|
+
raise Exception, "no threads" unless threads.any?(&:alive?)
|
26
|
+
|
22
27
|
queue.push([block, args])
|
23
28
|
end
|
24
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: forward-proxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Moriarty
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-07-
|
11
|
+
date: 2021-07-23 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Forward proxy using just Ruby standard libraries.
|
14
14
|
email:
|
@@ -32,6 +32,7 @@ files:
|
|
32
32
|
- exe/forward-proxy
|
33
33
|
- forward-proxy.gemspec
|
34
34
|
- lib/forward_proxy.rb
|
35
|
+
- lib/forward_proxy/errors/connection_timeout_error.rb
|
35
36
|
- lib/forward_proxy/errors/http_method_not_implemented.rb
|
36
37
|
- lib/forward_proxy/errors/http_parse_error.rb
|
37
38
|
- lib/forward_proxy/server.rb
|