proxifier2 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +19 -0
- data/README.md +120 -0
- data/bin/pirb +8 -0
- data/bin/pruby +8 -0
- data/lib/proxifier/env.rb +113 -0
- data/lib/proxifier/proxies/http.rb +19 -0
- data/lib/proxifier/proxies/socks.rb +103 -0
- data/lib/proxifier/proxies/socks4.rb +44 -0
- data/lib/proxifier/proxies/socks4a.rb +9 -0
- data/lib/proxifier/proxy.rb +63 -0
- data/lib/proxifier/version.rb +3 -0
- data/lib/proxifier.rb +25 -0
- data/lib/uri/socks.rb +26 -0
- data/proxifier2.gemspec +16 -0
- metadata +59 -0
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,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
|
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
|
data/proxifier2.gemspec
ADDED
@@ -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: []
|