forward-proxy 0.6.2 → 0.9.1

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: 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: