rendezvous 0.0.1

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.
data/lib/rendezvous.rb ADDED
@@ -0,0 +1,104 @@
1
+ require "rendezvous/version"
2
+
3
+ require "openssl"
4
+ require "socket"
5
+ require "uri"
6
+
7
+ class Rendezvous
8
+
9
+ module Errors
10
+ class Error < StandardError; end
11
+
12
+ class Authentication < Error; end
13
+
14
+ class Connection < Error; end
15
+
16
+ class Timeout < Error; end
17
+ class ActivityTimeout < Timeout; end
18
+ class ConnectionTimeout < Timeout; end
19
+ end
20
+
21
+ DEFAULT_CHUNK_SIZE = 1048576 # 1 megabyte
22
+
23
+ attr_reader :activity_timeout, :connect_timeout, :input, :output, :url
24
+
25
+ def self.start(options={})
26
+ rendezvous = self.new(options)
27
+ rendezvous.start
28
+ end
29
+
30
+ def initialize(options={})
31
+ @activity_timeout = options[:activity_timeout]
32
+ @connect_timeout = options[:connect_timeout] || 120
33
+ @input = options[:input] || $stdin
34
+ @output = options[:output] || $stdout
35
+ @url = options[:url]
36
+ end
37
+
38
+ def start
39
+ begin
40
+ `stty -icanon -echo` if input.isatty
41
+ loop do
42
+ if selected = IO.select([socket, input], nil, nil, activity_timeout)
43
+ if selected.first.first == input
44
+ socket.write(input.readpartial(DEFAULT_CHUNK_SIZE))
45
+ socket.flush
46
+ else
47
+ output.write(socket.readpartial(DEFAULT_CHUNK_SIZE))
48
+ end
49
+ else
50
+ raise Rendezvous::Errors::ActivityTimeout
51
+ end
52
+ end
53
+ rescue EOFError, Errno::EIO
54
+ rescue Interrupt
55
+ socket.write(3.chr)
56
+ socket.flush
57
+ retry
58
+ rescue SignalException => e
59
+ if Signal.list["QUIT"] == e.signo
60
+ socket.write(28.chr)
61
+ socket.flush
62
+ retry
63
+ end
64
+ raise
65
+ ensure
66
+ `stty icanon echo` if input.isatty
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def socket
73
+ @socket ||= begin
74
+ uri = URI.parse(url)
75
+ host, port, secret = uri.host, uri.port, uri.path[1..-1]
76
+
77
+ ssl_context = OpenSSL::SSL::SSLContext.new
78
+ ssl_context.ca_file = File.expand_path("../data/cacert.pem", __FILE__)
79
+ ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
80
+
81
+ Timeout.timeout(connect_timeout) do
82
+ tcp_socket = TCPSocket.open(host, port)
83
+ ssl_socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, ssl_context)
84
+ ssl_socket.connect
85
+ ssl_socket.sync_close = true
86
+
87
+ ssl_socket.hostname = host # SNI
88
+ ssl_socket.post_connection_check(host)
89
+
90
+ ssl_socket.puts(secret)
91
+ ssl_socket.readline
92
+
93
+ ssl_socket
94
+ end
95
+ rescue Errno::ECONNREFUSED, Errno::ECONNRESET
96
+ raise Rendezvous::Errors::Connection
97
+ rescue OpenSSL::SSL::SSLError
98
+ raise Rendezvous::Errors::Authentication
99
+ rescue Timeout::Error
100
+ raise Rendezvous::Errors::ConnectionTimeout
101
+ end
102
+ end
103
+
104
+ end
@@ -0,0 +1,3 @@
1
+ class Rendezvous
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rendezvous/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "rendezvous"
8
+ gem.version = Rendezvous::VERSION
9
+ gem.authors = ["geemus"]
10
+ gem.email = ["geemus@gmail.com"]
11
+ gem.description = %q{Client for interacting with Heroku processes.}
12
+ gem.summary = %q{Client for interacting with Heroku processes.}
13
+ gem.homepage = "http://github.com/heroku/rendezvous.rb"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rendezvous
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - geemus
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-10 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Client for interacting with Heroku processes.
15
+ email:
16
+ - geemus@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - Gemfile
23
+ - Gemfile.lock
24
+ - LICENSE.txt
25
+ - README.md
26
+ - Rakefile
27
+ - data/cacert.pem
28
+ - lib/rendezvous.rb
29
+ - lib/rendezvous/version.rb
30
+ - rendezvous.gemspec
31
+ homepage: http://github.com/heroku/rendezvous.rb
32
+ licenses: []
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ segments:
44
+ - 0
45
+ hash: 2376978038075154548
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ segments:
53
+ - 0
54
+ hash: 2376978038075154548
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 1.8.23
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: Client for interacting with Heroku processes.
61
+ test_files: []