em-socksify 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # EM-Socksify: Transparent SOCKS support for any EventMachine protocol
1
+ # Transparent proxy support for any EventMachine protocol
2
2
 
3
- Dealing with SOCKS proxies is pain. EM-Socksify provides a simple shim to setup & negotiate a SOCKS5 connection for any EventMachine protocol. To add SOCKS support, all you have to do is include the module and provide your destination address.
3
+ Dealing with SOCKS and HTTP proxies is a pain. EM-Socksify provides a simple ship to setup and negotiation a SOCKS / HTTP connection for any EventMachine protocol.
4
4
 
5
- ## Example: Routing HTTP request via SOCKS5 proxy
5
+ ### Example: Routing HTTP request via SOCKS5 proxy
6
6
 
7
7
  ```ruby
8
8
  class Handler < EM::Connection
@@ -24,9 +24,9 @@ EM.run do
24
24
  end
25
25
  ```
26
26
 
27
- What's happening here? First, we open a raw TCP connection to the SOCKS proxy (after all, all data will flow through it). Then, we provide a Handler connection class, which includes "EM::Socksify". Once the TCP connection is established, EventMachine calls the **connection_completed** method in our handler. Here, we call socksify with the actual destination host & port (address that we actually want to get to), and the module does the rest.
27
+ What's happening here? First, we open a raw TCP connection to the SOCKS proxy. Once the TCP connection is established, EventMachine calls the **connection_completed** method in our handler, at which point we call the helper method (**socksify**) with the actual destination and host and port (address that we actually want to get to), and the module does the rest.
28
28
 
29
- After you call socksify, the module temporarily intercepts your receive_data callbacks, negotiates the SOCKS connection (version, authentication, etc), and then once all is done, returns the control back to your code. Simple as that.
29
+ socksify temporarily intercepts your receive_data callbacks, negotiates the SOCKS connection (version, authentication, etc), and then once all of that is done, returns control back to your code.
30
30
 
31
31
  For SOCKS proxies which require authentication, use:
32
32
 
@@ -34,17 +34,51 @@ For SOCKS proxies which require authentication, use:
34
34
  socksify(destination_host, destination_port, username, password, version)
35
35
  ```
36
36
 
37
- ## Wishlist
37
+ ### Example: Routing HTTPS request via a squid CONNECT proxy
38
+
39
+ ```ruby
40
+ class Handler < EM::Connection
41
+ include EM::Connectify
42
+
43
+ def connection_completed
44
+ connectify('www.google.ca', 443) do
45
+ start_tls
46
+ send_data "GET / HTTP/1.1\r\nConnection:close\r\nHost: www.google.ca\r\n\r\n"
47
+ end
48
+ end
49
+
50
+ def receive_data(data)
51
+ p data
52
+ end
53
+ end
54
+
55
+ EM.run do
56
+ EventMachine.connect PROXY_HOST, PROXY_PORT, Handler
57
+ end
58
+ ```
59
+
60
+ For CONNECT proxies which require authentication, use:
61
+
62
+ ```ruby
63
+ connectify(destination_host, destination_port, username, password)
64
+ ```
65
+
66
+ ### Wishlist
38
67
 
39
68
  - IPV6 support
40
69
  - SOCKS4 support
41
70
 
42
- ## Resources
71
+ ### Resources
43
72
 
44
73
  - [SOCKS on Wikipedia](http://en.wikipedia.org/wiki/SOCKS)
45
74
  - [Socksify-Ruby](https://github.com/astro/socksify-ruby) for regular Ruby TCPSocket
75
+ - [HTTP Connect Tunneling](http://en.wikipedia.org/wiki/HTTP_tunnel#HTTP_CONNECT_Tunneling)
76
+
77
+ ### Contributors
78
+
79
+ - [Ilya Grigorik](https://github.com/igrigorik)
80
+ - [Conrad Irwin](https://github.com/ConradIrwin)
46
81
 
47
- # License
82
+ ### License
48
83
 
49
84
  (The MIT License)
50
- Copyright © 2011 Ilya Grigorik
data/em-socksify.gemspec CHANGED
@@ -9,13 +9,14 @@ Gem::Specification.new do |s|
9
9
  s.authors = ["Ilya Grigorik"]
10
10
  s.email = ["ilya@igvita.com"]
11
11
  s.homepage = "http://github.com/igrigorik/em-socksify"
12
- s.summary = "EventMachine SOCKSify shim: adds SOCKS support to any protocol"
12
+ s.summary = "Transparent proxy support for any EventMachine protocol"
13
13
  s.description = s.summary
14
14
 
15
15
  s.rubyforge_project = "em-socksify"
16
16
 
17
17
  s.add_dependency "eventmachine", ">= 1.0.0.beta.4"
18
18
  s.add_development_dependency "rspec"
19
+ s.add_development_dependency "rake"
19
20
 
20
21
  s.files = `git ls-files`.split("\n")
21
22
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
data/lib/em-socksify.rb CHANGED
@@ -1,5 +1,15 @@
1
1
  require 'eventmachine'
2
+ require 'base64'
2
3
 
3
4
  require 'em-socksify/socksify'
4
5
  require 'em-socksify/errors'
5
6
  require 'em-socksify/socks5'
7
+ require 'em-socksify/connectify'
8
+ require 'em-socksify/connect'
9
+
10
+ # Backport from ruby-1.9 to ruby-1.8 (which doesn't support pack('m0') either)
11
+ unless Base64.respond_to?(:strict_encode64)
12
+ def Base64.strict_encode64(str)
13
+ Base64.encode64(str).gsub("\n", "")
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ module EventMachine
2
+ module Connectify
3
+ module CONNECT
4
+ def connect_send_handshake
5
+ header = "CONNECT #{@connect_target_host}:#{@connect_target_port} HTTP/1.0\r\n"
6
+ if @connect_username || @connect_password
7
+ encoded_credentials = Base64.strict_encode64([@connect_username, @connect_password].join(":"))
8
+ header << "Proxy-Authorization: Basic #{encoded_credentials}\r\n"
9
+ end
10
+
11
+ header << "\r\n"
12
+ send_data(header)
13
+ end
14
+
15
+ private
16
+
17
+ def connect_parse_response
18
+ unless @connect_data =~ %r{\AHTTP/1\.[01] 200 .*\r\n\r\n}m
19
+ raise CONNECTError.new, "Unexpected response: #{@connect_data}"
20
+ end
21
+
22
+ connect_unhook
23
+ rescue => e
24
+ @connect_deferrable.fail e
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,41 @@
1
+ module EventMachine
2
+
3
+ module Connectify
4
+ def connectify(host, port, username=nil, password=nil, &blk)
5
+ @connect_target_host = host
6
+ @connect_target_port = port
7
+ @connect_username = username
8
+ @connect_password = password
9
+ @connect_data = ''
10
+
11
+ connect_hook
12
+ connect_send_handshake
13
+
14
+ @connect_deferrable = DefaultDeferrable.new
15
+ @connect_deferrable.callback(&blk) if blk
16
+ @connect_deferrable
17
+ end
18
+
19
+ def connect_hook
20
+ extend CONNECT
21
+
22
+ class << self
23
+ alias receive_data connect_receive_data
24
+ end
25
+ end
26
+
27
+ def connect_unhook
28
+ class << self
29
+ remove_method :receive_data
30
+ end
31
+
32
+ @connect_deferrable.succeed
33
+ end
34
+
35
+ def connect_receive_data(data)
36
+ @connect_data << data
37
+ connect_parse_response
38
+ end
39
+ end
40
+
41
+ end
@@ -35,4 +35,9 @@ module EventMachine
35
35
  end
36
36
 
37
37
  end
38
+
39
+ module Connectify
40
+ class CONNECTError < Exception
41
+ end
42
+ end
38
43
  end
@@ -1,7 +1,5 @@
1
1
  module EventMachine
2
-
3
- module Socksify
4
- VERSION = "0.2.1"
5
- end
6
-
2
+ module Socksify
3
+ VERSION = "0.3.0"
4
+ end
7
5
  end
@@ -2,14 +2,15 @@ require 'helper'
2
2
 
3
3
  describe EventMachine do
4
4
 
5
+ # requires: ssh -D 8080 localhost
5
6
  it "should negotiate a socks connection" do
6
7
 
7
8
  class Handler < EM::Connection
8
9
  include EM::Socksify
9
10
 
10
11
  def connection_completed
11
- socksify('google.ca', 80) do |ip|
12
- send_data "GET / HTTP/1.1\r\nConnection:close\r\nHost: google.ca\r\n\r\n"
12
+ socksify('google.com', 80) do |ip|
13
+ send_data "GET / HTTP/1.1\r\nConnection:close\r\nHost: google.com\r\n\r\n"
13
14
  end
14
15
  end
15
16
 
@@ -30,4 +31,35 @@ describe EventMachine do
30
31
  end
31
32
  end
32
33
 
34
+ # requires squid running on localhost with default config
35
+ it "should negotiate a connect connection" do
36
+
37
+ class Handler < EM::Connection
38
+ include EM::Connectify
39
+
40
+ def connection_completed
41
+ connectify('www.google.com', 443) do
42
+ start_tls
43
+ send_data "GET / HTTP/1.1\r\nConnection:close\r\nHost: www.google.com\r\n\r\n"
44
+ end
45
+ end
46
+
47
+ def receive_data(data)
48
+ @received ||= ''
49
+ @received << data
50
+ end
51
+
52
+ def unbind
53
+ @received.size.should > 0
54
+ @received[0,4].should == 'HTTP'
55
+ EM.stop
56
+ end
57
+ end
58
+
59
+ EM::run do
60
+ EventMachine.connect '127.0.0.1', 8081, Handler
61
+ end
62
+
63
+ end
64
+
33
65
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em-socksify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-11 00:00:00.000000000 Z
12
+ date: 2013-06-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
@@ -43,7 +43,23 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
- description: ! 'EventMachine SOCKSify shim: adds SOCKS support to any protocol'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Transparent proxy support for any EventMachine protocol
47
63
  email:
48
64
  - ilya@igvita.com
49
65
  executables: []
@@ -51,12 +67,13 @@ extensions: []
51
67
  extra_rdoc_files: []
52
68
  files:
53
69
  - .gitignore
54
- - .rspec
55
70
  - Gemfile
56
71
  - README.md
57
72
  - Rakefile
58
73
  - em-socksify.gemspec
59
74
  - lib/em-socksify.rb
75
+ - lib/em-socksify/connect.rb
76
+ - lib/em-socksify/connectify.rb
60
77
  - lib/em-socksify/errors.rb
61
78
  - lib/em-socksify/socks5.rb
62
79
  - lib/em-socksify/socksify.rb
@@ -86,7 +103,7 @@ rubyforge_project: em-socksify
86
103
  rubygems_version: 1.8.24
87
104
  signing_key:
88
105
  specification_version: 3
89
- summary: ! 'EventMachine SOCKSify shim: adds SOCKS support to any protocol'
106
+ summary: Transparent proxy support for any EventMachine protocol
90
107
  test_files:
91
108
  - spec/helper.rb
92
109
  - spec/socksify_spec.rb
data/.rspec DELETED
File without changes