proxifier2 1.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d830d99c1026cd8eca1768e28ce88fbd16c0619aa36c2625a8ff45370af332d6
4
+ data.tar.gz: e56d24c40e9523d0d5fd1e47429e77bdbde3b19a9bce40512e6902796a677fb7
5
+ SHA512:
6
+ metadata.gz: b06d8785f76c63fc8fe1751e256accacecfb93db3613cb4e55020a85c0db6c285f938ec01063f34e82bba4dae67c3aa3c8781fa5701001d80fa11d83f53f85b6
7
+ data.tar.gz: 2733802592c8ad91ec36d357b5cf77b265098e82d29aeb22a65bcdb282c548c9a5eec82d412e215bae93cb1788a482ea22b8595b4c12658058b02a96a40e97ba
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2011 by Samuel Kadolph
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # ruby-proxifier
2
+
3
+ ## Installing
4
+
5
+ ### Recommended
6
+
7
+ ```
8
+ gem install proxifier
9
+ ```
10
+
11
+ ### Edge
12
+
13
+ ```
14
+ git clone https://github.com/samuelkadolph/ruby-proxifier
15
+ cd ruby-proxifier && rake install
16
+ ```
17
+
18
+ ## Rationale
19
+
20
+ This gem was created for 2 purposes.
21
+
22
+ First is to enable ruby programmers to use HTTP or SOCKS proxies
23
+ interchangeably when using TCPSockets. Either manually with
24
+ `Proxifier::Proxy#open` or by `require "proxifier/env"`.
25
+
26
+ The second purpose is to use ruby code that doesn't use proxies for users that
27
+ have to use proxies.<br>The pruby and pirb executables are simple wrappers for
28
+ their respective ruby executables that support proxies from environment
29
+ variables.
30
+
31
+ ## Usage
32
+
33
+ ### Executable Wrappers & Environment Variables
34
+
35
+ proxifier provides two executables: `pruby` and `pirb`. They are simple
36
+ wrappers for your current `ruby` and `irb` executables that requires the
37
+ `"proxifier/env"` script which installs hooks into `TCPSocket` which will use
38
+ the proxy environment variables to proxy any `TCPSocket`.
39
+
40
+ The environment variables that proxifier will check are (in order of descending
41
+ precedence):
42
+
43
+ <table>
44
+ <tr>
45
+ <th>Variable Name</th>
46
+ <th>Alternatives</th>
47
+ <th>Notes</th>
48
+ </tr>
49
+ <tr>
50
+ <td>proxy</td>
51
+ <td>PROXY</td>
52
+ <td>Requires the proxy scheme to be present.</td>
53
+ </tr>
54
+ <tr>
55
+ <td>socks_proxy</td>
56
+ <td>SOCKS_PROXY<br>socks5_proxy<br>SOCKS5_PROXY</td>
57
+ <td>Implies the SOCKS5 proxy scheme.</td>
58
+ </tr>
59
+ <tr>
60
+ <td>socks4a_proxy</td>
61
+ <td>SOCKS4A_PROXY</td>
62
+ <td>Implies the SOCKS4A proxy scheme.</td>
63
+ </tr>
64
+ <tr>
65
+ <td>socks4_proxy</td>
66
+ <td>PROXY</td>
67
+ <td>Implies the SOCKS4 proxy scheme.</td>
68
+ </tr>
69
+ <tr>
70
+ <td>http_proxy</td>
71
+ <td>HTTP_PROXY</td>
72
+ <td>Implies the HTTP proxy scheme.</td>
73
+ </tr>
74
+ </table>
75
+
76
+ ### Ruby
77
+
78
+ ```ruby
79
+ require "proxifier/proxy"
80
+
81
+ proxy = Proxifier::Proxy("socks://localhost")
82
+ socket = proxy.open("www.google.com", 80)
83
+ socket << "GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n"
84
+ socket.gets # => "HTTP/1.1 200 OK\r\n"
85
+ ```
86
+
87
+ ## Supported Proxies
88
+
89
+ <table>
90
+ <tr>
91
+ <th>Protocol</th>
92
+ <th>Formats</th>
93
+ <th>Notes</th>
94
+ </tr>
95
+ <tr>
96
+ <td>HTTP</td>
97
+ <td><pre>http://[username[:password]@]host[:port][?tunnel=false]</pre></td>
98
+ <td>
99
+ The port defaults to 80. This is currently a limitation that may be solved in the future.<br>
100
+ Appending <code>?tunnel=false</code> forces the proxy to not use <code>CONNECT</code>.</td>
101
+ </tr>
102
+ <tr>
103
+ <td>SOCKS5</td>
104
+ <td><pre>socks://[username[:password]@]host[:port]
105
+ socks5://[username[:password]@]host[:port]</pre></td>
106
+ <td>
107
+ Port defaults to 1080.
108
+ </td>
109
+ </tr>
110
+ <tr>
111
+ <td>SOCKS4A</td>
112
+ <td><pre>socks4a://[username@]host[:port]</pre></td>
113
+ <td>Not yet implemented.</td>
114
+ </tr>
115
+ <tr>
116
+ <td>SOCKS4</td>
117
+ <td><pre>socks4://[username@]host[:port]</pre></td>
118
+ <td>Currently hangs. Not sure if the problem is with code or server.</td>
119
+ </tr>
120
+ </table>
data/bin/pirb ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ executable = File.expand_path("../" + Gem.default_exec_format % "irb", Gem.ruby)
4
+ full_gem_path = Gem.loaded_specs["proxifier"].full_gem_path
5
+ load_paths = Gem.loaded_specs["proxifier"].require_paths.map { |p| "-I#{File.join(full_gem_path, p)}" }
6
+ # TODO: support argument switches
7
+
8
+ exec(executable, *load_paths, "-rproxifier/env", *ARGV)
data/bin/pruby ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ executable = Gem.ruby
4
+ full_gem_path = Gem.loaded_specs["proxifier"].full_gem_path
5
+ load_paths = Gem.loaded_specs["proxifier"].require_paths.map { |p| "-I#{File.join(full_gem_path, p)}" }
6
+ # TODO: support argument switches
7
+
8
+ exec(executable, *load_paths, "-rproxifier/env", *ARGV)
@@ -0,0 +1,113 @@
1
+ require "socket"
2
+ require "proxifier"
3
+
4
+ module Proxifier
5
+ class Proxy
6
+ def open(host, port, local_host = nil, local_port = nil)
7
+ return TCPSocket.new(host, port, local_host, local_port, :proxy => nil) unless proxify?(host)
8
+
9
+ socket = TCPSocket.new(self.host, self.port, local_host, local_port, :proxy => nil)
10
+
11
+ begin
12
+ proxify(socket, host, port)
13
+ rescue
14
+ socket.close
15
+ raise
16
+ end
17
+
18
+ socket
19
+ end
20
+ end
21
+
22
+ module Proxify
23
+ def self.included(klass)
24
+ klass.class_eval do
25
+ alias_method :initialize_without_proxy, :initialize
26
+ alias_method :initialize, :initialize_with_proxy
27
+ end
28
+ end
29
+
30
+ def initialize_with_proxy(host, port, options_or_local_host = {}, local_port = nil, options_if_local_host = {})
31
+ if options_or_local_host.is_a?(Hash)
32
+ local_host = nil
33
+ options = options_or_local_host
34
+ else
35
+ local_host = options_or_local_host
36
+ options = options_if_local_host
37
+ end
38
+
39
+ if options[:proxy] && (proxy = Proxifier::Proxy(options.delete(:proxy), options)) && proxy.proxify?(host)
40
+ initialize_without_proxy(proxy.host, proxy.port, local_host, local_port)
41
+ begin
42
+ proxy.proxify(self, host, port)
43
+ rescue
44
+ close
45
+ raise
46
+ end
47
+ else
48
+ initialize_without_proxy(host, port, local_host, local_port)
49
+ end
50
+ end
51
+ end
52
+
53
+ module EnvironmentProxify
54
+ def self.included(klass)
55
+ klass.class_eval do
56
+ extend ClassMethods
57
+ alias_method :initialize_without_environment_proxy, :initialize
58
+ alias_method :initialize, :initialize_with_environment_proxy
59
+ end
60
+ end
61
+
62
+ def initialize_with_environment_proxy(host, port, options_or_local_host = {}, local_port = nil, options_if_local_host = {})
63
+ if options_or_local_host.is_a?(Hash)
64
+ local_host = nil
65
+ options = options_or_local_host
66
+ else
67
+ local_host = options_or_local_host
68
+ options = options_if_local_host
69
+ end
70
+
71
+ options = { :proxy => environment_proxy, :no_proxy => environment_no_proxy }.merge(options)
72
+ initialize_without_environment_proxy(host, port, local_host, local_port, options)
73
+ end
74
+
75
+ def environment_proxy
76
+ self.class.environment_proxy
77
+ end
78
+
79
+ def environment_no_proxy
80
+ self.class.environment_no_proxy
81
+ end
82
+
83
+ module ClassMethods
84
+ def environment_proxy
85
+ ENV["proxy"] || ENV["PROXY"] || specific_environment_proxy
86
+ end
87
+
88
+ def environment_no_proxy
89
+ ENV["no_proxy"] || ENV["NO_PROXY"]
90
+ end
91
+
92
+ private
93
+ def specific_environment_proxy
94
+ %w(socks socks5 socks4a socks4 http).each do |type|
95
+ if proxy = ENV["#{type}_proxy"] || ENV["#{type.upcase}_PROXY"]
96
+ scheme = "#{type}://"
97
+
98
+ proxy = proxy.dup
99
+ proxy.insert(0, scheme) unless proxy.index(scheme) == 0
100
+ return proxy
101
+ end
102
+ end
103
+
104
+ nil
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ class TCPSocket
111
+ include Proxifier::Proxify
112
+ include Proxifier::EnvironmentProxify
113
+ end
@@ -0,0 +1,19 @@
1
+ require "net/http"
2
+ require "proxifier/proxy"
3
+
4
+ module Proxifier
5
+ class HTTPProxy < Proxy
6
+ def do_proxify(socket, host, port)
7
+ return if query_options["tunnel"] == "false"
8
+
9
+ socket << "CONNECT #{host}:#{port} HTTP/1.1\r\n"
10
+ socket << "Host: #{host}:#{port}\r\n"
11
+ socket << "Proxy-Authorization: Basic #{["#{user}:#{password}"].pack("m").chomp}\r\n" if user
12
+ socket << "\r\n"
13
+
14
+ buffer = Net::BufferedIO.new(socket)
15
+ response = Net::HTTPResponse.read_new(buffer)
16
+ response.error! unless response.is_a?(Net::HTTPOK)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,103 @@
1
+ require "ipaddr"
2
+ require "proxifier/proxy"
3
+
4
+ module Proxifier
5
+ class SOCKSProxy < Proxy
6
+ VERSION = 0x05
7
+
8
+ def do_proxify(socket, host, port)
9
+ authenticaton_method = greet(socket)
10
+ authenticate(socket, authenticaton_method)
11
+ connect(socket, host, port)
12
+ end
13
+
14
+ protected
15
+ def greet(socket)
16
+ methods = authentication_methods
17
+
18
+ socket << [VERSION, methods.size, *methods].pack("CCC#{methods.size}")
19
+ version, authentication_method = socket.read(2).unpack("CC")
20
+ check_version(version)
21
+
22
+ authentication_method
23
+ end
24
+
25
+ def authenticate(socket, method)
26
+ case method
27
+ when 0x00 # NO AUTHENTICATION REQUIRED
28
+ when 0x02 # USERNAME/PASSWORD
29
+ user &&= user[0, 0xFF]
30
+ password &&= password[0, 0xFF]
31
+
32
+ socket << [user.size, user, password.size, password].pack("CA#{user.size}CA#{password.size}")
33
+ version, status = socket.read(2).unpack("CC")
34
+ check_version(version)
35
+
36
+ case status
37
+ when 0x00 # SUCCESS
38
+ else
39
+ raise "SOCKS5 username/password authentication failed"
40
+ end
41
+ else
42
+ raise "no acceptable SOCKS5 authentication methods"
43
+ end
44
+ end
45
+
46
+ def connect(socket, host, port)
47
+ host = host[0, 0xFF]
48
+ socket << [VERSION, 0x01, 0x00, 0x03, host.size, host, port].pack("CCCCCA#{host.size}n")
49
+ version, status, _, type = socket.read(4).unpack("CCCC")
50
+ check_version(version)
51
+
52
+ case status
53
+ when 0x00 # succeeded
54
+ when 0x01 # general SOCKS server failure
55
+ raise "general SOCKS server failure"
56
+ when 0x02 # connection not allowed by ruleset
57
+ raise "connection not allowed by ruleset"
58
+ when 0x03 # Network unreachable
59
+ raise "network unreachable"
60
+ when 0x04 # Host unreachable
61
+ raise "host unreachable"
62
+ when 0x05 # Connection refused
63
+ raise "connection refused"
64
+ when 0x06 # TTL expired
65
+ raise "TTL expired"
66
+ when 0x07 # Command not supported
67
+ raise "command not supported"
68
+ when 0x08 # Address type not supported
69
+ raise "address type not supported"
70
+ else # unassigned
71
+ raise "unknown SOCKS error"
72
+ end
73
+
74
+ case type
75
+ when 0x01 # IP V4 address
76
+ destination = IPAddr.ntop(socket.read(4))
77
+ when 0x03 # DOMAINNAME
78
+ length = socket.read(1).unpack("C").first
79
+ destination = socket.read(length).unpack("A#{length}")
80
+ when 0x04 # IP V6 address
81
+ destination = IPAddr.ntop(socket.read(16))
82
+ else
83
+ raise "unsupported SOCKS5 address type"
84
+ end
85
+
86
+ port = socket.read(2).unpack("n").first
87
+ end
88
+
89
+ def check_version(version, should_be = VERSION)
90
+ raise "mismatched SOCKS version" unless version == should_be
91
+ end
92
+
93
+ private
94
+ def authentication_methods
95
+ methods = []
96
+ methods << 0x00 # NO AUTHENTICATION REQUIRED
97
+ methods << 0x02 if user # USERNAME/PASSWORD
98
+ methods
99
+ end
100
+ end
101
+
102
+ SOCKS5Proxy = SOCKSProxy
103
+ end
@@ -0,0 +1,44 @@
1
+ require "proxifier/proxies/socks"
2
+
3
+ module Proxifier
4
+ class SOCKS4Proxy < SOCKSProxy
5
+ VERSION = 0x04
6
+
7
+ protected
8
+ def greet(socket)
9
+ # noop
10
+ end
11
+
12
+ def authenticate(socket, method)
13
+ # noop
14
+ end
15
+
16
+ def connect(socket, host, port)
17
+ begin
18
+ ip = IPAddr.new(host)
19
+ rescue ArgumentError
20
+ ip = IPAddr.new(Socket.getaddrinfo(host, nil, :INET, :STREAM).first)
21
+ end
22
+
23
+ socket << [VERSION, 0x01, port].pack("CCn") << ip.hton
24
+ socket << user if user
25
+ socket << 0x00
26
+
27
+ version, status, port = socket.read(4).unpack("CCn")
28
+ check_version(version, 0x00)
29
+ ip = IPAddr.ntop(socket.read(4))
30
+
31
+ case status
32
+ when 0x5A # request granted
33
+ when 0x5B # request rejected or failed
34
+ raise "request rejected or failed"
35
+ when 0x5C # request rejected becasue SOCKS server cannot connect to identd on the client
36
+ raise "request rejected becasue SOCKS server cannot connect to identd on the client"
37
+ when 0x5D # request rejected because the client program and identd report different user-ids
38
+ raise "request rejected because the client program and identd report different user-ids"
39
+ else
40
+ raise "unknown SOCKS error"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,9 @@
1
+ require "proxifier/proxies/socks"
2
+
3
+ module Proxifier
4
+ class SOCKS4AProxy < SOCKSProxy
5
+ def do_proxify(*)
6
+ raise NotImplementedError, "SOCKS4A is not yet implemented"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,63 @@
1
+ require "socket"
2
+ require "uri"
3
+ require "uri/socks"
4
+
5
+ module Proxifier
6
+ class Proxy
7
+ class << self
8
+ def proxify?(host, no_proxy = nil)
9
+ return true unless no_proxy
10
+
11
+ dont_proxy = no_proxy.split(",")
12
+ dont_proxy.none? { |h| host =~ /#{h}\Z/ }
13
+ end
14
+ end
15
+
16
+ attr_reader :url, :options
17
+
18
+ def initialize(url, options = {})
19
+ url = URI.parse(uri) unless url.is_a?(URI::Generic)
20
+ @url, @options = url, options
21
+ end
22
+
23
+ def open(host, port, local_host = nil, local_port = nil)
24
+ return TCPSocket.new(host, port, local_host, local_port) unless proxify?(host)
25
+
26
+ socket = TCPSocket.new(self.host, self.port, local_host, local_port)
27
+
28
+ begin
29
+ proxify(socket, host, port)
30
+ rescue
31
+ socket.close
32
+ raise
33
+ end
34
+
35
+ socket
36
+ end
37
+
38
+ def proxify?(host)
39
+ self.class.proxify?(host, options[:no_proxy])
40
+ end
41
+
42
+ def proxify(socket, host, port)
43
+ do_proxify(socket, host, port)
44
+ end
45
+
46
+ %w(host port user password query version).each do |attr|
47
+ class_eval "def #{attr}; url.#{attr} end"
48
+ end
49
+
50
+ def query_options
51
+ @query_options ||= query ? Hash[query.split("&").map { |q| q.split("=") }] : {}
52
+ end
53
+
54
+ %w(no_proxy).each do |option|
55
+ class_eval "def #{option}; options[:#{option}] end"
56
+ end
57
+
58
+ protected
59
+ def do_proxify(socket, host, port)
60
+ raise NotImplementedError, "#{self} must implement do_proxify"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,3 @@
1
+ module Proxifier
2
+ VERSION = "1.1.0"
3
+ end
data/lib/proxifier.rb ADDED
@@ -0,0 +1,25 @@
1
+ require "uri"
2
+ require "uri/socks"
3
+
4
+ module Proxifier
5
+ require "proxifier/version"
6
+
7
+ autoload :HTTPProxy, "proxifier/proxies/http"
8
+ autoload :SOCKSProxy, "proxifier/proxies/socks"
9
+ autoload :SOCKS5Proxy, "proxifier/proxies/socks"
10
+ autoload :SOCKS4Proxy, "proxifier/proxies/socks4"
11
+ autoload :SOCKS4AProxy, "proxifier/proxies/socks4a"
12
+
13
+ def self.Proxy(url, options = {})
14
+ url = URI.parse(url)
15
+
16
+ raise(ArgumentError, "proxy url has no scheme") unless url.scheme
17
+ begin
18
+ klass = const_get("#{url.scheme.upcase}Proxy")
19
+ rescue NameError
20
+ raise(ArgumentError, "unknown proxy scheme `#{url.scheme}'")
21
+ end
22
+
23
+ klass.new(url, options)
24
+ end
25
+ end
data/lib/uri/socks.rb ADDED
@@ -0,0 +1,26 @@
1
+ require "uri/generic"
2
+
3
+ module URI
4
+ class SOCKS < Generic
5
+ DEFAULT_PORT = 1080
6
+ COMPONENT = [:scheme, :userinfo, :host, :port, :query].freeze
7
+ end
8
+
9
+ class SOCKS4 < SOCKS
10
+ end
11
+
12
+ class SOCKS4A < SOCKS
13
+ end
14
+
15
+ begin
16
+ @@schemes["SOCKS4"] = SOCKS4
17
+ @@schemes["SOCKS"] = SOCKS
18
+ @@schemes["SOCKS5"] = SOCKS
19
+ @@schemes["SOCKS4A"] = SOCKS4A
20
+ rescue
21
+ register_scheme 'SOCKS4', SOCKS4
22
+ register_scheme 'SOCKS', SOCKS
23
+ register_scheme 'SOCKS5', SOCKS
24
+ register_scheme 'SOCKS4A', SOCKS4A
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require "proxifier/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "proxifier2"
6
+ s.version = Proxifier::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["Samuel Kadolph"]
9
+ s.email = ["samuel@kadolph.com"]
10
+ s.homepage = "https://github.com/chef/ruby-proxifier"
11
+ s.summary = %q{Proxifier is a gem to force ruby to use a proxy.}
12
+ s.description = %q{Proxifier adds support for HTTP or SOCKS proxies and lets you force TCPSocket to use proxies.}
13
+
14
+ s.files = Dir["bin/*", "lib/**/*"] + ["LICENSE", "README.md", "proxifier2.gemspec"]
15
+ s.executables = ["pirb", "pruby"]
16
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: proxifier2
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Samuel Kadolph
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-02-28 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Proxifier adds support for HTTP or SOCKS proxies and lets you force TCPSocket
14
+ to use proxies.
15
+ email:
16
+ - samuel@kadolph.com
17
+ executables:
18
+ - pirb
19
+ - pruby
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - LICENSE
24
+ - README.md
25
+ - bin/pirb
26
+ - bin/pruby
27
+ - lib/proxifier.rb
28
+ - lib/proxifier/env.rb
29
+ - lib/proxifier/proxies/http.rb
30
+ - lib/proxifier/proxies/socks.rb
31
+ - lib/proxifier/proxies/socks4.rb
32
+ - lib/proxifier/proxies/socks4a.rb
33
+ - lib/proxifier/proxy.rb
34
+ - lib/proxifier/version.rb
35
+ - lib/uri/socks.rb
36
+ - proxifier2.gemspec
37
+ homepage: https://github.com/chef/ruby-proxifier
38
+ licenses: []
39
+ metadata: {}
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubygems_version: 3.3.7
56
+ signing_key:
57
+ specification_version: 4
58
+ summary: Proxifier is a gem to force ruby to use a proxy.
59
+ test_files: []