em-connectify 0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MWVlNTYwYjNiOGE1Y2FmMGIzYzU2YmFlMTkyNjQ0MzUxMjAwODFkMg==
5
+ data.tar.gz: !binary |-
6
+ MzU4MzE1MTI0MjIyZWU5MmYzMWU3YWQ3MTFhMThlMzA5MGE0NmE3NQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ MTM2NGI0ZTg2YjBkOGMwZWUwODhkNWM5Y2FmZmY3ZTc5Zjg0ZTY2OWY0MTM3
10
+ YWI1MWZkMzc2YTc1MzU4OTcwYzNiY2Q3NjdhMzcyZmZhYWM4YjA1NjU5OWJj
11
+ MDg5MGFhZmVmOGJkNmNiMjZjOTEyY2NiOWE1MDVjZTY5M2UwMmQ=
12
+ data.tar.gz: !binary |-
13
+ ODRlOTg0YmU0MDg5MTNhOTI0MjVjOGJmMWY5ZGY1M2IzMjNjZTg1MDE5YTcz
14
+ ODg4MjVmNmFlZGJmZjgzNWIyMDAwNGRmMmRhYWNiNWVhNTFiMjllYWQ1NGQ2
15
+ OTllNzVmNGYxYWY0NWJjMjk0MTg5NWU1NjFiN2NiZGI4YWY2ZjI=
data/LICENSE.MIT ADDED
@@ -0,0 +1,20 @@
1
+ Copyright © 2013 Conrad Irwin
2
+ Includes substantial portions of em-socksify, Copyright © 2011 Ilya Grigorik
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # EM-Connectify: Transparent CONNECT support for any EventMachine protocol
2
+
3
+ Heavily based on igrigorik's [em-socksify](https://github.com/igrigorik/em-socksify), em-connectify provides a simple shim to send an eventmachine connection via an HTTP CONNECT proxy.
4
+
5
+ ## Example
6
+ ```ruby
7
+ class Handler < EM::Connection
8
+ include EM::Connectify
9
+
10
+ def connection_completed
11
+ connectify('google.ca', 80) do
12
+ send_data "GET / HTTP/1.1\r\nConnection:close\r\nHost: google.ca\r\n\r\n"
13
+ end
14
+ end
15
+
16
+ def receive_data
17
+ p data
18
+ end
19
+ end
20
+
21
+ EM.run do
22
+ EventMachine.connect PROXY_HOST, PROXY_PORT, Handler
23
+ end
24
+ ```
25
+
26
+ What's happening here? First, we open a raw TCP connection to the CONNECT proxy (after all, all data will flow through it). Then, we provide a Handler connection class, which includes "EM::Connectify". Once the TCP connection is established, EventMachine calls the **connection_completed** method in our handler. Here, we call connectify with the actual destination host & port (address that we actually want to get to), and the module does the rest.
27
+
28
+ After you call connectify, the module temporarily intercepts your receive_data callbacks, negotiates the connection, and then once all is done, returns the control back to your code. Simple as that.
29
+
30
+ ### Authorization
31
+
32
+ If you need to log into your proxy server, pass the username and password to `connectify` and em-connectify will send a `Proxy-Authorization: Basic` header.
33
+
34
+ ```ruby
35
+ connectify('google.ca', 80, 'username', 'password')
36
+ ```
@@ -0,0 +1,21 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "em-connectify"
3
+ s.version = "0.2"
4
+ s.platform = Gem::Platform::RUBY
5
+ s.authors = ["Conrad Irwin"]
6
+ s.email = ["conrad.irwin@gmail.com"]
7
+ s.homepage = "http://github.com/ConradIrwin/em-connectify"
8
+ s.summary = "EventMachine CONNECTify shim: adds CONNECT support to any protocol"
9
+ s.description = s.summary + '.'
10
+ s.license = 'MIT'
11
+
12
+ s.rubyforge_project = "em-connectify"
13
+
14
+ s.add_dependency "eventmachine", ">= 1.0.0.beta.4"
15
+ s.add_development_dependency "rspec"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
@@ -0,0 +1,12 @@
1
+ require 'eventmachine'
2
+ require 'base64'
3
+ require File.expand_path('em-connectify/connectify.rb', File.dirname(__FILE__))
4
+ require File.expand_path('em-connectify/connect.rb', File.dirname(__FILE__))
5
+ require File.expand_path('em-connectify/errors.rb', File.dirname(__FILE__))
6
+
7
+ unless Base64.respond_to?(:strict_encode64)
8
+ # Backport from ruby-1.9 to ruby-1.8 (which doesn't support pack('m0') either)
9
+ def Base64.strict_encode64(str)
10
+ Base64.encode64(str).gsub("\n", "")
11
+ end
12
+ 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,42 @@
1
+
2
+ module EventMachine
3
+
4
+ module Connectify
5
+ def connectify(host, port, username=nil, password=nil, &blk)
6
+ @connect_target_host = host
7
+ @connect_target_port = port
8
+ @connect_username = username
9
+ @connect_password = password
10
+ @connect_data = ''
11
+
12
+ connect_hook
13
+ connect_send_handshake
14
+
15
+ @connect_deferrable = DefaultDeferrable.new
16
+ @connect_deferrable.callback(&blk) if blk
17
+ @connect_deferrable
18
+ end
19
+
20
+ def connect_hook
21
+ extend CONNECT
22
+
23
+ class << self
24
+ alias receive_data connect_receive_data
25
+ end
26
+ end
27
+
28
+ def connect_unhook
29
+ class << self
30
+ remove_method :receive_data
31
+ end
32
+
33
+ @connect_deferrable.succeed
34
+ end
35
+
36
+ def connect_receive_data(data)
37
+ @connect_data << data
38
+ connect_parse_response
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,5 @@
1
+ module EM
2
+ module Connectify
3
+ class CONNECTError < RuntimeError; end
4
+ end
5
+ end
@@ -0,0 +1,43 @@
1
+ require File.expand_path('../lib/em-connectify', File.dirname(__FILE__))
2
+
3
+ describe EventMachine do
4
+
5
+ it "should negotiate a connect connection" do
6
+
7
+ class Handler < EM::Connection
8
+ include EM::Connectify
9
+
10
+ def post_init
11
+ puts "asdhi"
12
+ end
13
+
14
+ def connection_completed
15
+ connectify('google.ca', 80, 'conrad', 'conrad') do
16
+ puts "ping"
17
+ send_data "GET / HTTP/1.1\r\nConnection:close\r\nHost: google.ca\r\n\r\n"
18
+ end.callback do
19
+ puts "ping"
20
+ end.errback do |e|
21
+ puts e
22
+ end
23
+ end
24
+
25
+ def receive_data(data)
26
+ @received ||= ''
27
+ @received << data
28
+ end
29
+
30
+ def unbind
31
+ @received.size.should > 0
32
+ @received[0,4].should == 'HTTP'
33
+ EM.stop
34
+ end
35
+ end
36
+
37
+ EM::run do
38
+ EventMachine.connect '127.0.0.1', 3129, Handler
39
+ end
40
+
41
+ end
42
+
43
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: em-connectify
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.2'
5
+ platform: ruby
6
+ authors:
7
+ - Conrad Irwin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-06-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: eventmachine
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0.beta.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.0.beta.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: ! 'EventMachine CONNECTify shim: adds CONNECT support to any protocol.'
42
+ email:
43
+ - conrad.irwin@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - LICENSE.MIT
49
+ - README.md
50
+ - em-connectify.gemspec
51
+ - lib/em-connectify.rb
52
+ - lib/em-connectify/connect.rb
53
+ - lib/em-connectify/connectify.rb
54
+ - lib/em-connectify/errors.rb
55
+ - spec/connectify_spec.rb
56
+ homepage: http://github.com/ConradIrwin/em-connectify
57
+ licenses:
58
+ - MIT
59
+ metadata: {}
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project: em-connectify
76
+ rubygems_version: 2.0.3
77
+ signing_key:
78
+ specification_version: 4
79
+ summary: ! 'EventMachine CONNECTify shim: adds CONNECT support to any protocol'
80
+ test_files:
81
+ - spec/connectify_spec.rb
82
+ has_rdoc: