forward-proxy 0.6.1 → 0.9.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: 7994877d0fdfd4f8c482823781a855c9af1199d9b45df5c65912eabcc2786180
4
- data.tar.gz: '093d490188f128068f1ea444063ed61732fbb583245865aad8a90d50ee0b8532'
3
+ metadata.gz: e40f32962fa3503f6269cee6997a1288ad7921b7d24462ff4258947778850f21
4
+ data.tar.gz: c1330120ddf74e8e644b051c9b7c30986f0b6a1428d2420c92d8d02649acb846
5
5
  SHA512:
6
- metadata.gz: 572ca92444d60284f302b38f020a3718a82fee8048b3d6fc10d389af97c479142e3219022ac4c85bc12189025877fc9ce4aab7eac6f853ec6f2ffa4ded392f63
7
- data.tar.gz: 113e37c5a6b6da31851464545c5b2774396835cdb23d794253ab81babce52392040adcfdc9d75e473851ea108dfa2f946c7071a2b4b3a13b737ac4ad08b94269
6
+ metadata.gz: 28ffbea37fa7cfa64e6cd40c56b4f9584d016f5b305567beb939b400e610592a79b7481a9e08171df210e454d37efa18848b7236cc720ffa79a18a001b020f5f
7
+ data.tar.gz: 054af3f071444d16b77c138e79cf616eef5096081805950cca99d4c0d1ca5352763c50482011b1c11f725dab78293949e3ec5ea678cea0ea782aa8c198a9f34a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.9.0
4
+
5
+ - bugfix chunked response behavior.
6
+
7
+ ## 0.8.0
8
+
9
+ - add http `head` support.
10
+ - add http `501` not implemented status response.
11
+
12
+ ## 0.7.0
13
+
14
+ - bugfix default threads from `4` to `128`.
15
+
3
16
  ## 0.6.0
4
17
 
5
18
  - add connection timeout to stop tracking connection from saturating client threads.
@@ -12,7 +12,7 @@ module ForwardProxy
12
12
  class Server
13
13
  attr_reader :bind_address, :bind_port, :logger, :timeout
14
14
 
15
- def initialize(bind_address: "127.0.0.1", bind_port: 9292, threads: 4, timeout: 1, logger: default_logger)
15
+ def initialize(bind_address: "127.0.0.1", bind_port: 9292, threads: 128, timeout: 300, logger: default_logger)
16
16
  @bind_address = bind_address
17
17
  @bind_port = bind_port
18
18
  @logger = logger
@@ -37,7 +37,7 @@ module ForwardProxy
37
37
 
38
38
  case req.request_method
39
39
  when METHOD_CONNECT then handle_tunnel(client_conn, req)
40
- when METHOD_GET, METHOD_POST then handle(client_conn, req)
40
+ when METHOD_GET, METHOD_HEAD, METHOD_POST then handle(client_conn, req)
41
41
  else
42
42
  raise Errors::HTTPMethodNotImplemented
43
43
  end
@@ -67,17 +67,18 @@ module ForwardProxy
67
67
 
68
68
  attr_reader :socket, :thread_pool
69
69
 
70
- # The following comments are from the IETF document
71
- # "Hypertext Transfer Protocol -- HTTP/1.1: Basic Rules"
72
- # https://datatracker.ietf.org/doc/html/rfc2616#section-2.2
73
-
74
70
  METHOD_CONNECT = "CONNECT"
75
71
  METHOD_GET = "GET"
72
+ METHOD_HEAD = "HEAD"
76
73
  METHOD_POST = "POST"
77
74
 
75
+ # The following comments are from the IETF document
76
+ # "Hypertext Transfer Protocol -- HTTP/1.1: Basic Rules"
77
+ # https://datatracker.ietf.org/doc/html/rfc2616#section-2.2
78
+
78
79
  # HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all
79
80
  # protocol elements except the entity-body.
80
- HEADER_EOP = "\r\n"
81
+ HTTP_EOP = "\r\n"
81
82
 
82
83
  # The following comments are from the IETF document
83
84
  # "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content"
@@ -113,7 +114,7 @@ module ForwardProxy
113
114
  # the request-target.
114
115
  client_conn.write <<~eos.chomp
115
116
  HTTP/1.1 200 OK
116
- #{HEADER_EOP}
117
+ #{HTTP_EOP}
117
118
  eos
118
119
 
119
120
  # The CONNECT method requests that the recipient establish a tunnel to
@@ -154,7 +155,7 @@ module ForwardProxy
154
155
  client_conn.puts <<~eos.chomp
155
156
  HTTP/1.1 #{resp.code}
156
157
  #{headers.map { |header, value| "#{header}: #{value}" }.join("\n")}
157
- #{HEADER_EOP}
158
+ #{HTTP_EOP}
158
159
  eos
159
160
 
160
161
  # The following comments are taken from:
@@ -165,6 +166,16 @@ module ForwardProxy
165
166
  # instead stream the body directly to an IO.
166
167
  resp.read_body do |chunk|
167
168
  client_conn << chunk
169
+ # The following comments are taken from:
170
+ # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding#directives
171
+
172
+ # Data is sent in a series of chunks. The Content-Length header is omitted in this case and
173
+ # at the beginning of each chunk you need to add the length of the current chunk in
174
+ # hexadecimal format, followed by '\r\n' and then the chunk itself, followed by another
175
+ # '\r\n'. The terminating chunk is a regular chunk, with the exception that its length
176
+ # is zero. It is followed by the trailer, which consists of a (possibly empty) sequence of
177
+ # header fields.
178
+ client_conn << HTTP_EOP if resp['Transfer-Encoding'] == 'chunked'
168
179
  end
169
180
  end
170
181
  end
@@ -173,6 +184,7 @@ module ForwardProxy
173
184
  def handle_error(client_conn, err)
174
185
  status_code = case err
175
186
  when Errors::ConnectionTimeoutError then 504
187
+ when Errors::HTTPMethodNotImplemented then 501
176
188
  else
177
189
  502
178
190
  end
@@ -180,7 +192,7 @@ module ForwardProxy
180
192
  client_conn.puts <<~eos.chomp
181
193
  HTTP/1.1 #{status_code}
182
194
  Via: #{HEADER_VIA}
183
- #{HEADER_EOP}
195
+ #{HTTP_EOP}
184
196
  eos
185
197
 
186
198
  logger.error(err.message)
@@ -196,6 +208,7 @@ module ForwardProxy
196
208
 
197
209
  klass = case req.request_method
198
210
  when METHOD_GET then Net::HTTP::Get
211
+ when METHOD_HEAD then Net::HTTP::Head
199
212
  when METHOD_POST then Net::HTTP::Post
200
213
  else
201
214
  raise Errors::HTTPMethodNotImplemented
@@ -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
- @size = size
7
- @queue = Queue.new
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
@@ -1,3 +1,3 @@
1
1
  module ForwardProxy
2
- VERSION = "0.6.1"
2
+ VERSION = "0.9.0"
3
3
  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.6.1
4
+ version: 0.9.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-17 00:00:00.000000000 Z
11
+ date: 2021-08-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Forward proxy using just Ruby standard libraries.
14
14
  email: