forward-proxy 0.1.4 → 0.1.5

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
  SHA1:
3
- metadata.gz: f0e621e13501a70783e49eb16c52fd937974bc7e
4
- data.tar.gz: 70488fc1e2147c6c181e1dbb102929fe81eb1ecb
3
+ metadata.gz: 3e94626ce91d870564fcbed5db9133ddee5a1167
4
+ data.tar.gz: 44c9c4e4ca3a4036a8c1e9698dac6a203c3fe367
5
5
  SHA512:
6
- metadata.gz: b5bd0ed7c697ea9ea8e3fb973e31f44947b2c9c5d1b7c23cc025580f82c3cdf16aaf238a9e0b831397c69bf803b5d04f02212553de968dfece8c52c5d1688104
7
- data.tar.gz: 9a0b6db5127d71f0351577232d744ff0497c04c35a6a6e70580894d109dd160910b7ec4144134c295bafd35add0c3a9d6e57c6c47f63ca7ec92f16c67fa10c67
6
+ metadata.gz: c13a9fa915fb77699702226408cbd160d61cd375789beb947299423c788594c7f5d7af3783624fcf5fb30e8521e8a5e98c4953e7f1b5c7e477a756bda153634b
7
+ data.tar.gz: 609126058336e8cc597c0df21b3a3cb65c4d1216d7af11d77dec09eda104c6277811d59b942d38c46f8776c0cf1b8f137d09778793343a88c138872f65b06b54
@@ -0,0 +1,25 @@
1
+ name: Command Line Interface
2
+
3
+ on: [pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-latest
8
+
9
+ strategy:
10
+ matrix:
11
+ ruby: [ '2.3', '2.7' ]
12
+
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - uses: ruby/setup-ruby@v1
16
+ with:
17
+ ruby-version: ${{ matrix.ruby }}
18
+ bundler-cache: true
19
+ - run: gem install forward-proxy
20
+ - run: |
21
+ exe/forward-proxy --h
22
+ exe/forward-proxy --help
23
+ exe/forward-proxy --binding 127.0.0.1 --port 3001 --threads 2 &
24
+ sleep 1
25
+ curl --fail -x http://127.0.0.1:3001 https://google.com/
@@ -1,5 +1,11 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.1.5
4
+
5
+ - stream http proxy requests.
6
+ - call shutdown on `Interrupt`
7
+ - remove waiting for the thread-pool to finish on shutdown and just close the server conn.
8
+
3
9
  ## 0.1.4
4
10
 
5
11
  - `accept` connections via thread pool.
data/Gemfile CHANGED
@@ -4,6 +4,7 @@ source "https://rubygems.org"
4
4
  gemspec
5
5
 
6
6
  gem "rake", "~> 12.0"
7
+ gem "yard", "~> 0.9"
7
8
  gem "minitest", "~> 5.0"
8
9
  gem "minitest-reporters", "~> 1.4"
9
10
  gem "simplecov", "~> 0.17"
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ![Gem Version][3] ![Gem][1] ![Build Status][2]
4
4
 
5
- 100LOC Ruby forward proxy using just standard libraries.
5
+ 100 LOC Ruby forward proxy using only standard libraries.
6
6
 
7
7
  ```
8
8
  $ forward-proxy --binding 0.0.0.0 --port 3182 --threads 2
data/Rakefile CHANGED
@@ -1,5 +1,12 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
+ require 'yard'
4
+
5
+ YARD::Rake::YardocTask.new do |t|
6
+ t.files = ['lib/**/*.rb', 'README', 'CHANGELOG', 'CODE_OF_CONDUCT']
7
+ t.options = []
8
+ t.stats_options = ['--list-undoc']
9
+ end
3
10
 
4
11
  Rake::TestTask.new(:test) do |t|
5
12
  t.libs << "test"
@@ -7,4 +14,16 @@ Rake::TestTask.new(:test) do |t|
7
14
  t.test_files = FileList["test/**/*_test.rb"]
8
15
  end
9
16
 
17
+ namespace :gh do
18
+ desc "Deploy yard docs to github pages"
19
+ task :pages => :yard do
20
+ `git add -f doc`
21
+ `git commit -am "update: $(date)"`
22
+ `git subtree split --prefix doc -b gh-pages`
23
+ `git push -f origin gh-pages:gh-pages`
24
+ `git branch -D gh-pages`
25
+ `git reset head~1`
26
+ end
27
+ end
28
+
10
29
  task :default => :test
@@ -24,13 +24,14 @@ module ForwardProxy
24
24
  log("Listening #{bind_address}:#{bind_port}")
25
25
 
26
26
  loop do
27
- # The following comments are from "man 2 accept"
27
+ # The following comments are from https://stackoverflow.com/q/5124320/273101
28
28
  #
29
- # The argument socket is a socket that has been created with socket(2), bound to an address with bind(2), and is listening for connections after a listen(2). accept() extracts the
30
- # first connection request on the queue of pending connections, creates a new socket with the same properties of socket, and allocates a new file descriptor for the socket. If no
31
- # pending connections are present on the queue, and the socket is not marked as non-blocking, accept() blocks the caller until a connection is present. If the socket is marked
32
- # non-blocking and no pending connections are present on the queue, accept() returns an error as described below. The accepted socket may not be used to accept more connections.
33
- # The original socket socket, remains open.
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.
34
35
  thread_pool.schedule(server.accept) do |client_conn|
35
36
  begin
36
37
  req = parse_req(client_conn)
@@ -44,9 +45,16 @@ module ForwardProxy
44
45
  raise HTTPMethodNotImplemented
45
46
  end
46
47
  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.
47
55
  client_conn.puts <<~eos.chomp
48
56
  HTTP/1.1 502
49
- Server: ForwardProxy
57
+ Via: #{HEADER_VIA}
50
58
  eos
51
59
 
52
60
  puts e.message
@@ -57,15 +65,12 @@ module ForwardProxy
57
65
  end
58
66
  end
59
67
  rescue Interrupt
60
- log("Exiting...")
61
- rescue Errno::EBADF => e
68
+ shutdown
69
+ rescue IOError, Errno::EBADF => e
62
70
  log(e.message, "ERROR")
63
71
  end
64
72
 
65
73
  def shutdown
66
- log("Closing client connections...")
67
- thread_pool.shutdown
68
-
69
74
  log("Stoping server...")
70
75
  server.close if server
71
76
  end
@@ -78,6 +83,17 @@ module ForwardProxy
78
83
  METHOD_GET = "GET"
79
84
  METHOD_POST = "POST"
80
85
 
86
+ # The following comments are from the IETF document
87
+ # "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content"
88
+ # https://tools.ietf.org/html/rfc7231#section-4.3.6
89
+
90
+ # A proxy MUST send an appropriate Via header field, as described
91
+ # below, in each message that it forwards. An HTTP-to-HTTP gateway
92
+ # MUST send an appropriate Via header field in each inbound request
93
+ # message and MAY send a Via header field in forwarded response
94
+ # messages.
95
+ HEADER_VIA = "HTTP/1.1 ForwardProxy"
96
+
81
97
  def handle_tunnel(client_conn, req)
82
98
  # The following comments are from the IETF document
83
99
  # "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content"
@@ -114,22 +130,19 @@ module ForwardProxy
114
130
  end
115
131
 
116
132
  def handle(client_conn, req)
117
- resp = Net::HTTP.start(req.host, req.port) do |http|
118
- http.request map_webrick_to_net_http_req(req)
133
+ Net::HTTP.start(req.host, req.port) do |http|
134
+ http.request(map_webrick_to_net_http_req(req)) do |resp|
135
+ client_conn.puts <<~eos.chomp
136
+ HTTP/1.1 #{resp.code}
137
+ Via: #{[HEADER_VIA, resp['Via']].compact.join(', ')}
138
+ #{resp.each.map { |header, value| "#{header}: #{value}" }.join("\n")}\n\n
139
+ eos
140
+
141
+ resp.read_body do |chunk|
142
+ client_conn << chunk
143
+ end
144
+ end
119
145
  end
120
-
121
- # A proxy MUST send an appropriate Via header field, as described
122
- # below, in each message that it forwards. An HTTP-to-HTTP gateway
123
- # MUST send an appropriate Via header field in each inbound request
124
- # message and MAY send a Via header field in forwarded response
125
- # messages.
126
- client_conn.puts <<~eos.chomp
127
- HTTP/1.1 #{resp.code}
128
- Via: #{["1.1 ForwardProxy", resp['Via']].compact.join(', ')}
129
- #{resp.each.map { |header, value| "#{header}: #{value}" }.join("\n")}
130
-
131
- #{resp.body}
132
- eos
133
146
  end
134
147
 
135
148
  def map_webrick_to_net_http_req(req)
@@ -1,3 +1,3 @@
1
1
  module ForwardProxy
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.5"
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.4
4
+ version: 0.1.5
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-15 00:00:00.000000000 Z
11
+ date: 2021-01-20 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Forward proxy using just Ruby standard libraries.
14
14
  email:
@@ -19,6 +19,7 @@ extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
21
  - ".github/workflows/ci.yaml"
22
+ - ".github/workflows/cli.yaml"
22
23
  - ".gitignore"
23
24
  - CHANGELOG.md
24
25
  - CODE_OF_CONDUCT.md