forward-proxy 0.1.5 → 0.2.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
- SHA1:
3
- metadata.gz: 3e94626ce91d870564fcbed5db9133ddee5a1167
4
- data.tar.gz: 44c9c4e4ca3a4036a8c1e9698dac6a203c3fe367
2
+ SHA256:
3
+ metadata.gz: 628359d25536c4190014c9e082fff41b2adef209f04a62d8a6b217c078f3b58b
4
+ data.tar.gz: 7834932b7242fd66c120d270a922e385a6a58ab63c65e8ce2b7957da43ba5a11
5
5
  SHA512:
6
- metadata.gz: c13a9fa915fb77699702226408cbd160d61cd375789beb947299423c788594c7f5d7af3783624fcf5fb30e8521e8a5e98c4953e7f1b5c7e477a756bda153634b
7
- data.tar.gz: 609126058336e8cc597c0df21b3a3cb65c4d1216d7af11d77dec09eda104c6277811d59b942d38c46f8776c0cf1b8f137d09778793343a88c138872f65b06b54
6
+ metadata.gz: 8c47ab1d691807a23ba779f1ae8d4feecd32300f8d840044f66a5cc2f40ccd33c095db60ca9e3f99fb3c8fd60c02ae46d5d8d07b6a4de6298bef24731fb57cb4
7
+ data.tar.gz: 609a35651496d98e4977f3691c7834efd58fe736615b3b4594e0bc61d11dad0088f11f535f6b287db85f95c1cc8ab55ea2a536447028b690d92ffd0aa3e60669
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.2.0
4
+
5
+ - Extract errors into module.
6
+
3
7
  ## 0.1.5
4
8
 
5
9
  - stream http proxy requests.
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ![Gem Version][3] ![Gem][1] ![Build Status][2]
4
4
 
5
- 100 LOC Ruby forward proxy using only standard libraries.
5
+ Minimal forward proxy using 150LOC and only standard libraries. Useful for development, testing, and learning.
6
6
 
7
7
  ```
8
8
  $ forward-proxy --binding 0.0.0.0 --port 3182 --threads 2
data/exe/forward-proxy CHANGED
@@ -7,7 +7,7 @@ options = {}
7
7
  OptionParser.new do |parser|
8
8
  parser.banner = "Usage: forward-proxy [options]"
9
9
 
10
- parser.on("-pPORT", "--port=PORT", "Bind to specified port. Default: 9292", String) do |bind_port|
10
+ parser.on("-pPORT", "--port=PORT", String, "Bind to specified port. Default: 9292") do |bind_port|
11
11
  options[:bind_port] = bind_port
12
12
  end
13
13
 
@@ -26,6 +26,5 @@ OptionParser.new do |parser|
26
26
  end.parse!
27
27
 
28
28
  require_relative '../lib/forward_proxy'
29
-
30
29
  server = ForwardProxy::Server.new(options)
31
30
  server.start
@@ -0,0 +1,5 @@
1
+ module ForwardProxy
2
+ module Errors
3
+ class HTTPMethodNotImplemented < StandardError; end
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module ForwardProxy
2
+ module Errors
3
+ class HTTPParseError < StandardError; end
4
+ end
5
+ end
@@ -1,12 +1,11 @@
1
- require 'forward_proxy/thread_pool'
2
1
  require 'socket'
3
2
  require 'webrick'
4
3
  require 'net/http'
4
+ require 'forward_proxy/errors/http_method_not_implemented'
5
+ require 'forward_proxy/errors/http_parse_error'
6
+ require 'forward_proxy/thread_pool'
5
7
 
6
8
  module ForwardProxy
7
- class HTTPMethodNotImplemented < StandardError; end
8
- class HTTPParseError < StandardError; end
9
-
10
9
  class Server
11
10
  attr_reader :bind_address, :bind_port
12
11
 
@@ -19,20 +18,12 @@ module ForwardProxy
19
18
  def start
20
19
  thread_pool.start
21
20
 
22
- @server = TCPServer.new(bind_address, bind_port)
21
+ @socket = TCPServer.new(bind_address, bind_port)
23
22
 
24
23
  log("Listening #{bind_address}:#{bind_port}")
25
24
 
26
25
  loop do
27
- # The following comments are from https://stackoverflow.com/q/5124320/273101
28
- #
29
- # accept(): POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD (accept() first appeared in 4.2BSD).
30
- #
31
- # We see that POSIX.1-2008 is a viable reference (check this for a description of relevant
32
- # standards for Linux systems). As already said in other answers, POSIX.1 standard specifies
33
- # accept function as (POSIX-)thread safe (as defined in Base Definitions, section 3.399 Thread Safe)
34
- # by not listing it on System Interfaces, section 2.9.1 Thread Safety.
35
- thread_pool.schedule(server.accept) do |client_conn|
26
+ thread_pool.schedule(socket.accept) do |client_conn|
36
27
  begin
37
28
  req = parse_req(client_conn)
38
29
 
@@ -42,16 +33,9 @@ module ForwardProxy
42
33
  when METHOD_CONNECT then handle_tunnel(client_conn, req)
43
34
  when METHOD_GET, METHOD_POST then handle(client_conn, req)
44
35
  else
45
- raise HTTPMethodNotImplemented
36
+ raise Errors::HTTPMethodNotImplemented
46
37
  end
47
38
  rescue => e
48
- # The following comments are from the IETF document
49
- # "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content"
50
- # https://tools.ietf.org/html/rfc7231#section-6.6.3
51
-
52
- # The 502 (Bad Gateway) status code indicates that the server, while
53
- # acting as a gateway or proxy, received an invalid response from an
54
- # inbound server it accessed while attempting to fulfill the request.
55
39
  client_conn.puts <<~eos.chomp
56
40
  HTTP/1.1 502
57
41
  Via: #{HEADER_VIA}
@@ -71,13 +55,16 @@ module ForwardProxy
71
55
  end
72
56
 
73
57
  def shutdown
74
- log("Stoping server...")
75
- server.close if server
58
+ if socket
59
+ log("Shutting down")
60
+
61
+ socket.close
62
+ end
76
63
  end
77
64
 
78
65
  private
79
66
 
80
- attr_reader :server, :thread_pool
67
+ attr_reader :socket, :thread_pool
81
68
 
82
69
  METHOD_CONNECT = "CONNECT"
83
70
  METHOD_GET = "GET"
@@ -138,6 +125,12 @@ module ForwardProxy
138
125
  #{resp.each.map { |header, value| "#{header}: #{value}" }.join("\n")}\n\n
139
126
  eos
140
127
 
128
+ # The following comments are taken from:
129
+ # https://docs.ruby-lang.org/en/2.0.0/Net/HTTP.html#class-Net::HTTP-label-Streaming+Response+Bodies
130
+
131
+ # By default Net::HTTP reads an entire response into memory. If you are
132
+ # handling large files or wish to implement a progress bar you can
133
+ # instead stream the body directly to an IO.
141
134
  resp.read_body do |chunk|
142
135
  client_conn << chunk
143
136
  end
@@ -152,13 +145,13 @@ module ForwardProxy
152
145
  when METHOD_GET then Net::HTTP::Get
153
146
  when METHOD_POST then Net::HTTP::Post
154
147
  else
155
- raise HTTPMethodNotImplemented
148
+ raise Errors::HTTPMethodNotImplemented
156
149
  end
157
150
 
158
151
  klass.new(req.path, req_headers)
159
152
  end
160
153
 
161
- def transfer(dest_conn, src_conn)
154
+ def transfer(src_conn, dest_conn)
162
155
  IO.copy_stream(src_conn, dest_conn)
163
156
  rescue => e
164
157
  log(e.message, "WARNING")
@@ -169,7 +162,7 @@ module ForwardProxy
169
162
  req.parse(client_conn)
170
163
  end
171
164
  rescue => e
172
- throw HTTPParseError.new(e.message)
165
+ throw Errors::HTTPParseError.new(e.message)
173
166
  end
174
167
 
175
168
  def log(str, level = 'INFO')
@@ -1,3 +1,3 @@
1
1
  module ForwardProxy
2
- VERSION = "0.1.5"
2
+ VERSION = "0.2.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.1.5
4
+ version: 0.2.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-01-20 00:00:00.000000000 Z
11
+ date: 2021-05-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Forward proxy using just Ruby standard libraries.
14
14
  email:
@@ -32,6 +32,8 @@ files:
32
32
  - exe/forward-proxy
33
33
  - forward-proxy.gemspec
34
34
  - lib/forward_proxy.rb
35
+ - lib/forward_proxy/errors/http_method_not_implemented.rb
36
+ - lib/forward_proxy/errors/http_parse_error.rb
35
37
  - lib/forward_proxy/server.rb
36
38
  - lib/forward_proxy/thread_pool.rb
37
39
  - lib/forward_proxy/version.rb
@@ -57,8 +59,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
57
59
  - !ruby/object:Gem::Version
58
60
  version: '0'
59
61
  requirements: []
60
- rubyforge_project:
61
- rubygems_version: 2.5.2.3
62
+ rubygems_version: 3.0.3
62
63
  signing_key:
63
64
  specification_version: 4
64
65
  summary: Forward proxy.