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/.gitignore +18 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +14 -0
- data/LICENSE.txt +22 -0
- data/README.md +54 -0
- data/Rakefile +1 -0
- data/data/cacert.pem +3988 -0
- data/lib/rendezvous.rb +104 -0
- data/lib/rendezvous/version.rb +3 -0
- data/rendezvous.gemspec +19 -0
- metadata +61 -0
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
|
data/rendezvous.gemspec
ADDED
@@ -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: []
|