waithook 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 119debffa9104d9f4b3b0c1d2a943840a0bb1aaa
4
+ data.tar.gz: ee89ce35a2bc6a13a3517f9c524b108d53c36d16
5
+ SHA512:
6
+ metadata.gz: e75927f077b2fa65d3a3af0855f314f68a4039996ae11ab641b1b2bdc58b43aaefa35196d2f6bf5728edde917729de5ed67880e58abcd85f3c57f6065a656e28
7
+ data.tar.gz: 07000675d72ef66ab760dde7d039e4fcbafa36186d4f06ecc18e0912ad4b829d89dcfb2454c110480f190dce8017cade2acba2adddac6548c69c48768e9f29c0
@@ -0,0 +1 @@
1
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem 'rake'
4
+ gem 'minitest-reporters'
5
+ gem 'excon'
6
+ gem 'addressable'
7
+
8
+ gemspec
@@ -0,0 +1,37 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ waithook (0.1)
5
+ websocket (~> 1.2.3)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ addressable (2.5.0)
11
+ public_suffix (~> 2.0, >= 2.0.2)
12
+ ansi (1.5.0)
13
+ builder (3.2.2)
14
+ excon (0.54.0)
15
+ minitest (5.9.1)
16
+ minitest-reporters (1.1.12)
17
+ ansi
18
+ builder
19
+ minitest (>= 5.0)
20
+ ruby-progressbar
21
+ public_suffix (2.0.4)
22
+ rake (11.3.0)
23
+ ruby-progressbar (1.8.1)
24
+ websocket (1.2.3)
25
+
26
+ PLATFORMS
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ addressable
31
+ excon
32
+ minitest-reporters
33
+ rake
34
+ waithook!
35
+
36
+ BUNDLED WITH
37
+ 1.13.6
@@ -0,0 +1,4 @@
1
+
2
+ task :test do
3
+ Dir.glob('./tests/**/*_test.rb').each { |file| require file }
4
+ end
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.push(File.expand_path("../../lib", __FILE__))
4
+
@@ -0,0 +1,54 @@
1
+ require 'looksee'
2
+ require 'net/http'
3
+
4
+ require './websocket-client'
5
+
6
+ HOST = 'localhost'
7
+ PORT = 3012
8
+ #HOST = 'waithook.herokuapp.com'
9
+ #PORT = 80
10
+
11
+ client = WebsocketClient.new(host: HOST, port: PORT, path: 'test-ruby')
12
+
13
+ client.connect!
14
+
15
+ sleep 1
16
+
17
+ client.send_ping!
18
+
19
+ def print_time(message)
20
+ s_time = Time.now.to_f
21
+ r = yield
22
+ puts "Time #{message}: #{Time.now.to_f - s_time}"
23
+ r
24
+ end
25
+
26
+ sleep 5
27
+
28
+ Net::HTTP.start(HOST, PORT) do |http|
29
+ while true
30
+ sleep 2
31
+ print_time("HTTP Request") {
32
+ http.get("/test-ruby")
33
+ }
34
+ print_time("Waithook response") {
35
+ type, data = client.wait_message
36
+ #p [type, data]
37
+ }
38
+ #client.close!
39
+ #Net::HTTP.get(URI.parse("http://#{HOST}:#{PORT}/test-ruby"))
40
+ end
41
+ end
42
+
43
+ #socket = TCPSocket.open(hostname, port)
44
+ #
45
+ #request = WebSocket::Handshake::Client.new(url: 'ws://waithook.herokuapp.com/test-ruby')
46
+ #puts request
47
+ #
48
+ #socket.print(request)
49
+ #
50
+ #while line = socket.gets
51
+ # puts line.chop
52
+ #end
53
+ #
54
+ #socket.close
@@ -0,0 +1,64 @@
1
+ require 'looksee'
2
+ require 'net/http'
3
+ require "stringio"
4
+ require 'json'
5
+
6
+ require './websocket-client'
7
+
8
+ HOST = 'localhost'
9
+ PORT = 3012
10
+ #HOST = 'waithook.herokuapp.com'
11
+ #PORT = 80
12
+
13
+ threads_num = ENV['THREADS'] ? ENV['THREADS'].to_i : 10
14
+ threads = []
15
+ timing = {}
16
+ running = true
17
+
18
+ threads_num.times do
19
+ threads << Thread.new do
20
+ begin
21
+ client = WebsocketClient.new(host: HOST, port: PORT, path: 'pick-hour', output: StringIO.new)
22
+ client.connect!
23
+
24
+ while running
25
+ type, data = client.wait_message
26
+ body = JSON.parse(data)['body']
27
+ puts "Message time: #{Time.now.to_f - timing[body]} sec"
28
+ end
29
+
30
+ client.close!
31
+ puts "client done"
32
+ rescue Object => error
33
+ puts "#{error.class}: #{error.message}\n#{error.backtrace.join("\n")}"
34
+ raise error
35
+ end
36
+ end
37
+ end
38
+
39
+ sleep 3
40
+
41
+ Net::HTTP.start(HOST, PORT) do |http|
42
+ 200.times do |n|
43
+ msg = "aaa-#{n}"
44
+ timing[msg] = Time.now.to_f
45
+ puts "Sending #{msg}"
46
+ puts http.post('/pick-hour', msg)
47
+ sleep 0.05
48
+ end
49
+ end
50
+
51
+ #200.times do |n|
52
+ # msg = "aaa-#{n}"
53
+ # timing[msg] = Time.now.to_f
54
+ # puts "Sending #{msg}"
55
+ # Net::HTTP.start(HOST, PORT) do |http|
56
+ # puts http.post('/pick-hour', msg)
57
+ # end
58
+ # sleep 0.01
59
+ #end
60
+
61
+ #Net::HTTP.get(URI.parse("http://#{HOST}:#{PORT}/pick-hour"))
62
+
63
+ #p threads
64
+ threads.map(&:join)
@@ -0,0 +1,19 @@
1
+ require 'looksee'
2
+ require 'excon'
3
+
4
+ require './websocket-client'
5
+
6
+ #HOST = 'localhost'
7
+ #PORT = 3012
8
+ HOST = 'waithook.herokuapp.com'
9
+ PORT = 443
10
+
11
+ client = WebsocketClient.new(host: HOST, port: PORT, path: 'test-ruby').connect!.wait_handshake!
12
+
13
+ Excon.get("http#{PORT == 443 ? 's' : ''}://#{HOST}:#{PORT}/test-ruby")
14
+ type, data = client.wait_message
15
+
16
+ puts "Received message (#{type})"
17
+ puts "Received message body: #{data}"
18
+
19
+ client.close!
@@ -0,0 +1,11 @@
1
+ require_relative './waithook'
2
+ require 'excon'
3
+
4
+ waithook = Waithook.subscribe('my-super-test', host: 'localhost', port: 3012)
5
+
6
+ Excon.post('http://localhost:3012/my-super-test', body: Time.now.to_s)
7
+
8
+ while true
9
+ response = waithook.forward_to('http://localhost:3012/my-super-test')
10
+ p waithook.messages.last
11
+ end
@@ -0,0 +1,128 @@
1
+ require 'net/http'
2
+ require 'json'
3
+
4
+ require_relative 'waithook/websocket_client'
5
+
6
+ class Waithook
7
+
8
+ SERVER_HOST = "waithook.herokuapp.com"
9
+ SERVER_PORT = 443
10
+
11
+ def self.subscribe(path, options = {}, &block)
12
+ instance = new(path, options)
13
+ if block
14
+ instance.filter = block
15
+ end
16
+ instance.connect! unless instance.started?
17
+ instance
18
+ end
19
+
20
+ attr_accessor :filter
21
+ attr_accessor :messages
22
+ attr_reader :client
23
+
24
+ def initialize(path, options = {})
25
+ options = {
26
+ host: SERVER_HOST,
27
+ port: SERVER_PORT,
28
+ auto_connect: true
29
+ }.merge(options)
30
+
31
+ @path = path
32
+ @client = WebsocketClient.new(
33
+ path: path,
34
+ host: options[:host],
35
+ port: options[:port],
36
+ logger: options[:logger]
37
+ )
38
+
39
+ @messages = []
40
+ @filter = nil
41
+ @started = false
42
+
43
+ connect! if options[:auto_connect]
44
+ end
45
+
46
+ def connect!
47
+ raise "Waithook connection already started" if @started
48
+ @started = true
49
+ @client.connect!.wait_handshake!
50
+ self
51
+ end
52
+
53
+ def started?
54
+ !!@started
55
+ end
56
+
57
+ def forward_to(url)
58
+ webhook = wait_message
59
+
60
+ uri = URI.parse(url)
61
+ response = nil
62
+
63
+ Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
64
+ http_klass = case webhook.method
65
+ when "GET" then Net::HTTP::Get
66
+ when "POST" then Net::HTTP::Post
67
+ when "PUT" then Net::HTTP::Put
68
+ when "PATCH" then Net::HTTP::Patch
69
+ when "HEAD" then Net::HTTP::Head
70
+ when "DELETE" then Net::HTTP::Delete
71
+ when "MOVE" then Net::HTTP::Move
72
+ when "COPY" then Net::HTTP::Copy
73
+ when "HEAD" then Net::HTTP::Head
74
+ else Net::HTTP::Post
75
+ end
76
+
77
+ request = http_klass.new(uri)
78
+ webhook.headers.each do |key, value|
79
+ request[key] = value
80
+ end
81
+
82
+ if webhook.body
83
+ request.body = webhook.body
84
+ end
85
+
86
+ response = http.request(request)
87
+ end
88
+
89
+ response
90
+ end
91
+
92
+ def wait_message
93
+ while true
94
+ type, data = @client.wait_message
95
+ webhook = Webhook.new(data)
96
+ if @filter && @filter.call(webhook) || !@filter
97
+ @messages << webhook
98
+ return webhook
99
+ end
100
+ end
101
+ end
102
+
103
+ def close!
104
+ @client.close!
105
+ @started = false
106
+ end
107
+
108
+ class Webhook
109
+ attr_reader :url
110
+ attr_reader :headers
111
+ attr_reader :body
112
+ attr_reader :method
113
+
114
+ def initialize(payload)
115
+ data = JSON.parse(payload)
116
+ @url = data['url']
117
+ @headers = data['headers']
118
+ @body = data['body']
119
+ @method = data['method']
120
+ end
121
+
122
+ def json_body
123
+ if @body
124
+ @json_body ||= JSON.parse(@body)
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,3 @@
1
+ class Waithook
2
+ VERSION = "0.1"
3
+ end
@@ -0,0 +1,197 @@
1
+ require 'socket'
2
+ require 'logger'
3
+ require 'websocket'
4
+
5
+ class Waithook
6
+ class WebsocketClient
7
+
8
+ attr_accessor :logger
9
+
10
+ class Waiter
11
+ def wait
12
+ @queue = Queue.new
13
+ @queue.pop(false)
14
+ end
15
+
16
+ def notify(data)
17
+ @queue.push(data)
18
+ end
19
+ end
20
+
21
+ def initialize(options = {})
22
+ # required: :host, :path
23
+
24
+ @host = options[:host]
25
+ @port = options[:port] || 80
26
+ @path = options[:path]
27
+
28
+ @use_ssl = options.has_key?(:ssl) ? options[:ssl] : @port == 443
29
+ @options = options
30
+
31
+ @waiters = []
32
+ @handshake_received = false
33
+ @messages = Queue.new
34
+ @is_open = false
35
+
36
+ @output = options[:output] || STDOUT
37
+
38
+ if options[:logger] === false
39
+ @output = StringIO.new
40
+ end
41
+
42
+ if options[:logger]
43
+ @logger = options[:logger]
44
+ else
45
+ @logger = Logger.new(@output)
46
+ @logger.progname = self.class.name
47
+ @logger.formatter = proc do |serverity, time, progname, msg|
48
+ msg.lines.map do |line|
49
+ "#{progname} :: #{line}"
50
+ end.join("") + "\n"
51
+ end
52
+ end
53
+ end
54
+
55
+ def connect!
56
+ logger.info "Connecting to #{@host} #{@port}"
57
+
58
+ tcp_socket = TCPSocket.open(@host, @port)
59
+
60
+ if @use_ssl
61
+ require 'openssl'
62
+ ctx = OpenSSL::SSL::SSLContext.new
63
+ ctx.ssl_version = @options[:ssl_version] if @options[:ssl_version]
64
+ ctx.verify_mode = @options[:verify_mode] if @options[:verify_mode]
65
+ cert_store = OpenSSL::X509::Store.new
66
+ cert_store.set_default_paths
67
+ ctx.cert_store = cert_store
68
+ @socket = ::OpenSSL::SSL::SSLSocket.new(tcp_socket, ctx)
69
+ @socket.connect
70
+ else
71
+ @socket = tcp_socket
72
+ end
73
+
74
+ @is_open = true
75
+ @handshake = WebSocket::Handshake::Client.new(url: "ws://#{@host}/#{@path}")
76
+
77
+ logger.debug "Sending handshake:\n#{@handshake}"
78
+
79
+ @socket.print(@handshake)
80
+ _start_parser!
81
+
82
+ self
83
+ end
84
+
85
+ def connected?
86
+ !!@is_open
87
+ end
88
+
89
+ def _start_parser!
90
+ @reader, @writter = IO.pipe
91
+ @processing_thread = Thread.new do
92
+ Thread.current.abort_on_exception = true
93
+ begin
94
+ logger.debug "Start reading in thread"
95
+ handshake_response = _wait_handshake_response
96
+ @handshake << handshake_response
97
+ logger.debug "Handshake received:\n #{handshake_response}"
98
+
99
+ @frame_parser = WebSocket::Frame::Incoming::Client.new
100
+ @handshake_received = true
101
+ _wait_frames!
102
+ rescue Object => error
103
+ logger.error "#{error.class}: #{error.message}\n#{error.backtrace.join("\n")}"
104
+ raise error
105
+ end
106
+ end
107
+ end
108
+
109
+ def send_ping!
110
+ _send_frame(:ping)
111
+ end
112
+
113
+ def send_pong!
114
+ _send_frame(:pong)
115
+ end
116
+
117
+ def send_message!(payload)
118
+ _send_frame(:text, payload)
119
+ end
120
+
121
+ def wait_handshake!
122
+ while !@handshake_received
123
+ sleep 0.001
124
+ end
125
+ self
126
+ end
127
+
128
+ def wait_new_message
129
+ waiter = Waiter.new
130
+ @waiters << waiter
131
+ waiter.wait
132
+ end
133
+
134
+ def wait_message
135
+ @messages.pop
136
+ end
137
+
138
+ def _notify_waiters(type, payload)
139
+ while waiter = @waiters.shift
140
+ waiter.notify([type, payload])
141
+ end
142
+ end
143
+
144
+ def _send_frame(type, payload = nil)
145
+ wait_handshake!
146
+ frame = WebSocket::Frame::Outgoing::Client.new(version: @handshake.version, data: payload, type: type)
147
+ logger.debug "Sending :#{frame.type} #{payload ? "DATA: #{frame.data}" : "(no data)"}"
148
+ @socket.write(frame.to_s)
149
+ end
150
+
151
+ def _process_frame(message)
152
+ if message.type == :ping
153
+ send_pong!
154
+ end
155
+ if message.type == :text
156
+ @messages.push([message.type, message.data])
157
+ _notify_waiters(message.type, message.data)
158
+ end
159
+ end
160
+
161
+ def _wait_frames!
162
+ while char = @socket.getc
163
+ @frame_parser << char
164
+ while message = @frame_parser.next
165
+ _process_frame(message)
166
+ end
167
+ end
168
+ end
169
+
170
+ def _wait_handshake_response
171
+ logger.debug "Waiting handshake response"
172
+ data = []
173
+ while line = @socket.gets
174
+ data << line
175
+ if line == "\r\n"
176
+ break
177
+ end
178
+ end
179
+ data.join("")
180
+ end
181
+
182
+ def close!(options = {send_close: true})
183
+ unless @is_open
184
+ logger.info "Already closed"
185
+ return false
186
+ end
187
+
188
+ logger.info "Disconnecting from #{@host} #{@port}"
189
+ @processing_thread.kill
190
+ _send_frame(:close) if options[:send_close]
191
+ @socket.close
192
+ @is_open = false
193
+
194
+ return true
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,131 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe "Server" do
4
+ after do
5
+ @client.close! if @client && @client.connected?
6
+ assert_equal(0, get_stats['total_listeners'])
7
+ end
8
+
9
+ def default_client
10
+ Waithook::WebsocketClient.new(host: HOST, port: PORT, path: PATH, output: StringIO.new).connect!.wait_handshake!
11
+ end
12
+
13
+ it "should remove connection on disconnect with close frame" do
14
+ @client = default_client
15
+
16
+ POST(PATH, 'test data')
17
+ type, data = @client.wait_message
18
+ message = JSON.parse(data)
19
+
20
+ assert_equal(:text, type)
21
+ assert_equal('test data', message['body'])
22
+
23
+ @client.close!
24
+
25
+ assert_equal(0, get_stats['total_listeners'])
26
+ end
27
+
28
+ it "should remove connection after disconnect without close frame" do
29
+ @client = default_client
30
+
31
+ POST(PATH, 'test data')
32
+ type, data = @client.wait_message
33
+ message = JSON.parse(data)
34
+
35
+ assert_equal(:text, type)
36
+ assert_equal('test data', message['body'])
37
+
38
+ @client.close!(send_close: false)
39
+
40
+ assert_equal(0, get_stats['total_listeners'])
41
+ end
42
+
43
+ it "should show stats for subscribed connection" do
44
+ @client = default_client
45
+
46
+ response = GET('@/stats')
47
+ stats = JSON.parse(response.body)
48
+ @client.close!
49
+
50
+ assert_equal({'/test-ruby' => 1}, stats['listeners'])
51
+ assert_equal({
52
+ "Connection" => "close",
53
+ "Content-Length" => "116",
54
+ "Content-Type" => "application/json"
55
+ }, response.headers)
56
+ end
57
+
58
+ it "should not allow keep-alive" do
59
+ response = POST(PATH, 'test data')
60
+
61
+ assert_equal("OK\n", response.body)
62
+ assert_equal({
63
+ "Connection" => "close",
64
+ "Content-Length" => "3",
65
+ "Content-Type" => "text/plain"
66
+ }, response.headers)
67
+ end
68
+
69
+ it "should serve index.html" do
70
+ response = GET("")
71
+
72
+ assert_includes(response.body, "<html>")
73
+ assert_equal({
74
+ "Connection" => "close",
75
+ "Content-Length" => response.headers["Content-Length"],
76
+ "Content-Type" => "text/html"
77
+ }, response.headers)
78
+ end
79
+
80
+ it "should serve index.html" do
81
+ response = GET("@/index.js")
82
+
83
+ assert_includes(response.body, "function")
84
+ assert_equal({
85
+ "Connection" => "close",
86
+ "Content-Length" => response.headers["Content-Length"],
87
+ "Content-Type" => "application/javascript; charset=utf-8"
88
+ }, response.headers)
89
+ end
90
+
91
+ it "should support utf-8 content" do
92
+ @client = default_client
93
+
94
+ response = POST(PATH, "привет")
95
+ assert_includes(response.body, "OK\n")
96
+
97
+ type, data = @client.wait_message
98
+ message = JSON.parse(data)
99
+
100
+ assert_equal(:text, type)
101
+ assert_equal("привет", message['body'])
102
+ end
103
+
104
+ it "should support utf-8 paths" do
105
+ skip "hyper not support it yet"
106
+ path = "бум!!!"
107
+ @client = Waithook::WebsocketClient.new(host: HOST, port: PORT, path: path, output: StringIO.new).connect!
108
+ @client.wait_handshake!
109
+
110
+ response = POST(path, "test-body")
111
+ assert_includes(response.body, "OK\n")
112
+
113
+ type, data = @client.wait_message
114
+ message = JSON.parse(data)
115
+
116
+ assert_equal(:text, type)
117
+ assert_equal("test-body", message['body'])
118
+ end
119
+
120
+ it "should work with PUT" do
121
+ @client = default_client
122
+ response = Excon.put("http://#{HOST}:#{PORT}/#{PATH}", body: "test-data")
123
+
124
+ type, data = @client.wait_message
125
+ message = JSON.parse(data)
126
+
127
+ assert_equal(:text, type)
128
+ assert_equal("test-data", message['body'])
129
+ assert_equal("PUT", message['method'])
130
+ end
131
+ end
@@ -0,0 +1,45 @@
1
+ Encoding.default_internal = Encoding::UTF_8
2
+ Encoding.default_external = Encoding::UTF_8
3
+
4
+ require 'bundler/setup'
5
+ require_relative '../lib/waithook'
6
+
7
+ require 'excon'
8
+ require 'json'
9
+ require "minitest/autorun"
10
+ require "minitest/reporters"
11
+ require "addressable/uri"
12
+
13
+ Minitest::Reporters.use!(
14
+ Minitest::Reporters::SpecReporter.new(color: true)
15
+ )
16
+
17
+ if ENV['SEQ']
18
+ puts "Set test_order == :alpha"
19
+ class Minitest::Test
20
+ def self.test_order
21
+ :alpha
22
+ end
23
+ end
24
+ end
25
+
26
+ # To support UTF-8 in path
27
+ module WebSocket::Handshake
28
+ URI = Addressable::URI
29
+ end
30
+
31
+ HOST = 'localhost'
32
+ PORT = 3012
33
+ PATH = 'test-ruby'
34
+
35
+ def POST(path, data = nil)
36
+ Excon.post("http://#{HOST}:#{PORT}/#{path}", body: data, uri_parser: Addressable::URI)
37
+ end
38
+
39
+ def GET(path)
40
+ Excon.get("http://#{HOST}:#{PORT}/#{path}", uri_parser: Addressable::URI)
41
+ end
42
+
43
+ def get_stats
44
+ JSON.parse(GET('@/stats').body)
45
+ end
@@ -0,0 +1,57 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe "Waithook" do
4
+
5
+ before do
6
+ @waithook_instances = []
7
+ end
8
+
9
+ after do
10
+ @waithook_instances.map(&:close!).clear
11
+ end
12
+
13
+ def default_client(options = {})
14
+ client = Waithook.subscribe(options[:path] || 'my-super-test', host: HOST, port: PORT, logger: false)
15
+ @waithook_instances.push(client)
16
+ client
17
+ end
18
+
19
+ it "should subscribe" do
20
+ waithook = default_client
21
+
22
+ stats = get_stats
23
+ assert_equal(1, stats['total_listeners'])
24
+ assert_equal({"/my-super-test" => 1}, stats['listeners'])
25
+ end
26
+
27
+ it "should receive a message" do
28
+ waithook = default_client
29
+
30
+ message = JSON.generate([Time.now.to_s])
31
+ Excon.post("http://#{HOST}:#{PORT}/my-super-test", body: message)
32
+
33
+ webhook = waithook.wait_message
34
+ assert_instance_of(Waithook::Webhook, webhook)
35
+ assert_equal(message, webhook.body)
36
+ assert_equal(JSON.parse(message), webhook.json_body)
37
+ end
38
+
39
+ it "should forward request" do
40
+ waithook = default_client
41
+ second_client = default_client(path: 'my-super-test2')
42
+
43
+ message = {'my_data' => true}
44
+
45
+ Excon.post("http://#{HOST}:#{PORT}/my-super-test", body: JSON.generate(message))
46
+
47
+ server_response = waithook.forward_to("http://#{HOST}:#{PORT}/my-super-test2")
48
+
49
+ assert_instance_of(Net::HTTPOK, server_response)
50
+ assert_equal("OK\n", server_response.body)
51
+
52
+ webhook = second_client.wait_message
53
+
54
+ assert_equal(message, webhook.json_body)
55
+ assert_equal("POST", webhook.method)
56
+ end
57
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'lib/waithook/version'
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "waithook"
5
+ s.version = Waithook::VERSION
6
+ s.author = ["Pavel Evstigneev"]
7
+ s.email = ["pavel.evst@gmail.com"]
8
+ s.homepage = "https://github.com/paxa/waithook-ruby"
9
+ s.summary = %q{HTTP to WebSocket transmitting client}
10
+ s.description = "Waithook gem is client lib for waithook service https://waithook.heroku.com"
11
+ s.license = 'MIT'
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = []
15
+
16
+ s.require_paths = ["lib"]
17
+ s.executables = ["waithook"]
18
+
19
+ s.add_runtime_dependency "websocket", "~> 1.2"
20
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: waithook
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Pavel Evstigneev
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-11-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: websocket
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.2'
27
+ description: Waithook gem is client lib for waithook service https://waithook.heroku.com
28
+ email:
29
+ - pavel.evst@gmail.com
30
+ executables:
31
+ - waithook
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - Gemfile
37
+ - Gemfile.lock
38
+ - Rakefile
39
+ - bin/waithook
40
+ - example/example.rb
41
+ - example/many_clients.rb
42
+ - example/real_server_test.rb
43
+ - example/waithook_example.rb
44
+ - lib/waithook.rb
45
+ - lib/waithook/version.rb
46
+ - lib/waithook/websocket_client.rb
47
+ - tests/server_test.rb
48
+ - tests/test_helper.rb
49
+ - tests/waithook_test.rb
50
+ - waithook.gemspec
51
+ homepage: https://github.com/paxa/waithook-ruby
52
+ licenses:
53
+ - MIT
54
+ metadata: {}
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubyforge_project:
71
+ rubygems_version: 2.6.8
72
+ signing_key:
73
+ specification_version: 4
74
+ summary: HTTP to WebSocket transmitting client
75
+ test_files: []