forward-proxy 0.6.2 → 0.9.1

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: a1fe517be17887550c0afe7d8ad757227d79667083ad5530aa714a8e0b2398be
4
- data.tar.gz: 574b65e5fd8bf6e324f0657f8bfc87342481c5f177c87f1e9f2cffe49953db17
3
+ metadata.gz: ebb420c1a9dd1e13e77b0884f0349e3bb9f78150a9e00004bb6db86a95c3766d
4
+ data.tar.gz: 3186ebd3f6f1beadc466aeb81f1f427f43f62960dab3680ce9be8ed1efd5e0d4
5
5
  SHA512:
6
- metadata.gz: 34d36e4bfc21abaf59a75ecec4fa86b5d9157beb5e7f7437201f15689f584fb92076f6db5095929d52062b6c543a53d65bc81393bc5013204206d8f2c041c4d2
7
- data.tar.gz: 4e7c99b2485929fe9fb93da86256bd642ff56f8f93207b3cdd0eccc6606d4c6f53d64514adbf550831062185390ae5b1327619bfa26dcd2631ca817acab6c36d
6
+ metadata.gz: 5fc1d9053270cda730bd7ca85a5e08fa4a42105fe8a2a7d17cbfa0ac8b29d437a6dde6c5d884b336a5295c1ebaa842bc5c0e15cded11f309148e5253f1a7fd12
7
+ data.tar.gz: ee39eb4f082d8ba7e4bd7f7d0bf5233b763e0ce6ff787b531a549e8b3ab4caf1fd03831c71244a73e0ab570988e13762373d437bd42632effafcb4f783eebacc
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.9.1
4
+
5
+ - bugfix chunked length.
6
+
7
+ ## 0.9.0
8
+
9
+ - bugfix chunked response behavior.
10
+
11
+ ## 0.8.0
12
+
13
+ - add http `head` support.
14
+ - add http `501` not implemented status response.
15
+
16
+ ## 0.7.0
17
+
18
+ - bugfix default threads from `4` to `128`.
19
+
3
20
  ## 0.6.0
4
21
 
5
22
  - 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: 300, 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:
@@ -164,6 +165,17 @@ module ForwardProxy
164
165
  # handling large files or wish to implement a progress bar you can
165
166
  # instead stream the body directly to an IO.
166
167
  resp.read_body do |chunk|
168
+ # The following comments are taken from:
169
+ # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding#directives
170
+
171
+ # Data is sent in a series of chunks. The Content-Length header is omitted in this case and
172
+ # at the beginning of each chunk you need to add the length of the current chunk in
173
+ # hexadecimal format, followed by '\r\n' and then the chunk itself, followed by another
174
+ # '\r\n'. The terminating chunk is a regular chunk, with the exception that its length
175
+ # is zero. It is followed by the trailer, which consists of a (possibly empty) sequence of
176
+ # header fields.
177
+ client_conn << chunk.bytesize.to_s(16) + HTTP_EOP if resp['Transfer-Encoding'] == 'chunked'
178
+
167
179
  client_conn << chunk
168
180
  end
169
181
  end
@@ -173,6 +185,7 @@ module ForwardProxy
173
185
  def handle_error(client_conn, err)
174
186
  status_code = case err
175
187
  when Errors::ConnectionTimeoutError then 504
188
+ when Errors::HTTPMethodNotImplemented then 501
176
189
  else
177
190
  502
178
191
  end
@@ -180,7 +193,7 @@ module ForwardProxy
180
193
  client_conn.puts <<~eos.chomp
181
194
  HTTP/1.1 #{status_code}
182
195
  Via: #{HEADER_VIA}
183
- #{HEADER_EOP}
196
+ #{HTTP_EOP}
184
197
  eos
185
198
 
186
199
  logger.error(err.message)
@@ -196,6 +209,7 @@ module ForwardProxy
196
209
 
197
210
  klass = case req.request_method
198
211
  when METHOD_GET then Net::HTTP::Get
212
+ when METHOD_HEAD then Net::HTTP::Head
199
213
  when METHOD_POST then Net::HTTP::Post
200
214
  else
201
215
  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.2"
2
+ VERSION = "0.9.1"
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.2
4
+ version: 0.9.1
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: