rocket 0.0.1 → 0.0.2
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 +0 -11
- data/Rakefile +21 -34
- data/lib/rocket.rb +1 -6
- data/lib/rocket/version.rb +1 -1
- data/rocket.gemspec +20 -68
- metadata +25 -37
- data/bin/rocket +0 -1
- data/lib/rocket/channel.rb +0 -20
- data/lib/rocket/client.rb +0 -31
- data/lib/rocket/helpers.rb +0 -23
- data/lib/rocket/websocket.rb +0 -225
- data/spec/helpers_spec.rb +0 -21
- data/spec/rocket_spec.rb +0 -11
- data/spec/spec_helper.rb +0 -8
data/.gitignore
CHANGED
data/Rakefile
CHANGED
@@ -1,49 +1,19 @@
|
|
1
1
|
# -*- ruby -*-
|
2
|
-
|
3
2
|
$:.unshift(File.expand_path('../lib', __FILE__))
|
4
|
-
|
3
|
+
$:.unshift(File.expand_path('../../rocket-core/lib', __FILE__))
|
5
4
|
require 'rspec/core/rake_task'
|
6
5
|
require 'rake/rdoctask'
|
7
6
|
require 'rocket/version'
|
8
7
|
|
9
|
-
SUMMARY = %Q{Event-oriented WebSockets server and toolkit.}
|
10
|
-
DESCRIPTION = %Q{
|
11
|
-
Rocket is a very fast and reliable web socket server built upon em-websockets library.
|
12
|
-
Rocket provides also JavaScript toolkit to serve up instructions to clients, and
|
13
|
-
ruby library which handles events triggering. This Project was strongly inspired
|
14
|
-
by awesome PusherApp.
|
15
|
-
}
|
16
|
-
|
17
|
-
begin
|
18
|
-
require 'jeweler'
|
19
|
-
Jeweler::Tasks.new do |g|
|
20
|
-
g.version = Rocket.version
|
21
|
-
g.name = "rocket"
|
22
|
-
g.email = "chris@nu7hat.ch"
|
23
|
-
g.homepage = "http://github.com/araneo/rocket"
|
24
|
-
g.authors = ["Araneo", "Chris Kowalik"]
|
25
|
-
g.summary = SUMMARY
|
26
|
-
g.description = DESCRIPTION
|
27
|
-
g.add_dependency "rocket-server", "0.0.1"
|
28
|
-
g.add_dependency "rocket-js", "0.0.1"
|
29
|
-
g.add_dependency "json", "~> 1.4"
|
30
|
-
g.add_development_dependency "rspec", "~> 2.0"
|
31
|
-
g.add_development_dependency "mocha", "~> 0.9"
|
32
|
-
end
|
33
|
-
Jeweler::GemcutterTasks.new
|
34
|
-
rescue
|
35
|
-
puts 'Jeweler is not available here'
|
36
|
-
end
|
37
|
-
|
38
8
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
39
9
|
t.pattern = 'spec/**/*_spec.rb'
|
40
|
-
t.rspec_opts = %q[-Ilib -c -b]
|
10
|
+
t.rspec_opts = %q[-I../rocket-core/lib -Ilib -c -b]
|
41
11
|
end
|
42
12
|
|
43
13
|
RSpec::Core::RakeTask.new(:rcov) do |t|
|
44
14
|
t.rcov = true
|
45
|
-
t.rspec_opts = %q[-Ilib -c -b]
|
46
|
-
t.rcov_opts = %q[-Ilib -T -x "spec"]
|
15
|
+
t.rspec_opts = %q[-I../rocket-core/lib -Ilib -c -b]
|
16
|
+
t.rcov_opts = %q[-I../rocket-core/lib -Ilib -T -x "spec"]
|
47
17
|
end
|
48
18
|
|
49
19
|
Rake::RDocTask.new do |rdoc|
|
@@ -53,4 +23,21 @@ Rake::RDocTask.new do |rdoc|
|
|
53
23
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
54
24
|
end
|
55
25
|
|
26
|
+
desc "Build current version as a rubygem"
|
27
|
+
task :build do
|
28
|
+
sh "gem build rocket.gemspec"
|
29
|
+
sh "mkdir -p pkg"
|
30
|
+
sh "mv rocket-*.gem pkg/"
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Relase current version to rubygems.org"
|
34
|
+
task :release => :build do
|
35
|
+
sh "gem push pkg/rocket-#{Rocket.version}.gem"
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "Perform installation via rubygems"
|
39
|
+
task :install => :build do
|
40
|
+
sh "gem install pkg/rocket-#{Rocket.version}.gem"
|
41
|
+
end
|
42
|
+
|
56
43
|
task :default => :spec
|
data/lib/rocket.rb
CHANGED
data/lib/rocket/version.rb
CHANGED
data/rocket.gemspec
CHANGED
@@ -1,72 +1,24 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# -*- ruby -*-
|
2
|
+
$:.unshift(File.expand_path('../lib', __FILE__))
|
3
|
+
$:.unshift(File.expand_path('../../rocket/lib', __FILE__))
|
4
|
+
require 'rocket/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name
|
8
|
-
s.version
|
7
|
+
s.name = 'rocket'
|
8
|
+
s.version = Rocket.version
|
9
|
+
s.homepage = 'http://github.com/araneo/rocket'
|
10
|
+
s.email = ['chris@nu7hat.ch']
|
11
|
+
s.authors = ['Araneo Ltd.', 'Chris Kowalik']
|
12
|
+
s.summary = %q{Event-oriented WebSockets server and toolkit.}
|
13
|
+
s.description = %q{Rocket is a very fast and reliable web socket server built upon em-websockets library. Rocket provides also JavaScript toolkit to serve up instructions to clients, and ruby library which handles events triggering. This Project was strongly inspired by awesome PusherApp.}
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
16
|
+
s.require_paths = %w[lib]
|
17
|
+
s.extra_rdoc_files = %w[LICENSE README.md]
|
9
18
|
|
10
|
-
s.
|
11
|
-
s.
|
12
|
-
s.
|
13
|
-
s.
|
14
|
-
|
15
|
-
Rocket provides also JavaScript toolkit to serve up instructions to clients, and
|
16
|
-
ruby library which handles events triggering. This Project was strongly inspired
|
17
|
-
by awesome PusherApp.
|
18
|
-
}
|
19
|
-
s.email = %q{chris@nu7hat.ch}
|
20
|
-
s.extra_rdoc_files = [
|
21
|
-
"LICENSE",
|
22
|
-
"README.md"
|
23
|
-
]
|
24
|
-
s.files = [
|
25
|
-
".gitignore",
|
26
|
-
"LICENSE",
|
27
|
-
"README.md",
|
28
|
-
"Rakefile",
|
29
|
-
"bin/rocket",
|
30
|
-
"lib/rocket.rb",
|
31
|
-
"lib/rocket/channel.rb",
|
32
|
-
"lib/rocket/client.rb",
|
33
|
-
"lib/rocket/helpers.rb",
|
34
|
-
"lib/rocket/version.rb",
|
35
|
-
"lib/rocket/websocket.rb",
|
36
|
-
"rocket.gemspec",
|
37
|
-
"spec/helpers_spec.rb",
|
38
|
-
"spec/rocket_spec.rb",
|
39
|
-
"spec/spec_helper.rb"
|
40
|
-
]
|
41
|
-
s.homepage = %q{http://github.com/araneo/rocket}
|
42
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
43
|
-
s.require_paths = ["lib"]
|
44
|
-
s.rubygems_version = %q{1.3.7}
|
45
|
-
s.summary = %q{Event-oriented WebSockets server and toolkit.}
|
46
|
-
|
47
|
-
if s.respond_to? :specification_version then
|
48
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
49
|
-
s.specification_version = 3
|
50
|
-
|
51
|
-
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
52
|
-
s.add_runtime_dependency(%q<rocket-server>, ["= 0.0.1"])
|
53
|
-
s.add_runtime_dependency(%q<rocket-js>, ["= 0.0.1"])
|
54
|
-
s.add_runtime_dependency(%q<json>, ["~> 1.4"])
|
55
|
-
s.add_development_dependency(%q<rspec>, ["~> 2.0"])
|
56
|
-
s.add_development_dependency(%q<mocha>, ["~> 0.9"])
|
57
|
-
else
|
58
|
-
s.add_dependency(%q<rocket-server>, ["= 0.0.1"])
|
59
|
-
s.add_dependency(%q<rocket-js>, ["= 0.0.1"])
|
60
|
-
s.add_dependency(%q<json>, ["~> 1.4"])
|
61
|
-
s.add_dependency(%q<rspec>, ["~> 2.0"])
|
62
|
-
s.add_dependency(%q<mocha>, ["~> 0.9"])
|
63
|
-
end
|
64
|
-
else
|
65
|
-
s.add_dependency(%q<rocket-server>, ["= 0.0.1"])
|
66
|
-
s.add_dependency(%q<rocket-js>, ["= 0.0.1"])
|
67
|
-
s.add_dependency(%q<json>, ["~> 1.4"])
|
68
|
-
s.add_dependency(%q<rspec>, ["~> 2.0"])
|
69
|
-
s.add_dependency(%q<mocha>, ["~> 0.9"])
|
70
|
-
end
|
19
|
+
s.add_runtime_dependency 'rocket-core', [Rocket.version]
|
20
|
+
s.add_runtime_dependency 'rocket-js', [Rocket.version]
|
21
|
+
s.add_runtime_dependency 'rocket-server', [Rocket.version]
|
22
|
+
s.add_development_dependency 'rspec', ["~> 2.0"]
|
23
|
+
s.add_development_dependency 'mocha', [">= 0.9"]
|
71
24
|
end
|
72
|
-
|
metadata
CHANGED
@@ -1,38 +1,38 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rocket
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
|
-
- Araneo
|
13
|
+
- Araneo Ltd.
|
14
14
|
- Chris Kowalik
|
15
15
|
autorequire:
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-11-
|
19
|
+
date: 2010-11-09 00:00:00 +01:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
23
|
-
name: rocket-
|
23
|
+
name: rocket-core
|
24
24
|
prerelease: false
|
25
25
|
requirement: &id001 !ruby/object:Gem::Requirement
|
26
26
|
none: false
|
27
27
|
requirements:
|
28
28
|
- - "="
|
29
29
|
- !ruby/object:Gem::Version
|
30
|
-
hash:
|
30
|
+
hash: 27
|
31
31
|
segments:
|
32
32
|
- 0
|
33
33
|
- 0
|
34
|
-
-
|
35
|
-
version: 0.0.
|
34
|
+
- 2
|
35
|
+
version: 0.0.2
|
36
36
|
type: :runtime
|
37
37
|
version_requirements: *id001
|
38
38
|
- !ruby/object:Gem::Dependency
|
@@ -43,27 +43,28 @@ dependencies:
|
|
43
43
|
requirements:
|
44
44
|
- - "="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
hash:
|
46
|
+
hash: 27
|
47
47
|
segments:
|
48
48
|
- 0
|
49
49
|
- 0
|
50
|
-
-
|
51
|
-
version: 0.0.
|
50
|
+
- 2
|
51
|
+
version: 0.0.2
|
52
52
|
type: :runtime
|
53
53
|
version_requirements: *id002
|
54
54
|
- !ruby/object:Gem::Dependency
|
55
|
-
name:
|
55
|
+
name: rocket-server
|
56
56
|
prerelease: false
|
57
57
|
requirement: &id003 !ruby/object:Gem::Requirement
|
58
58
|
none: false
|
59
59
|
requirements:
|
60
|
-
- -
|
60
|
+
- - "="
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
hash:
|
62
|
+
hash: 27
|
63
63
|
segments:
|
64
|
-
-
|
65
|
-
-
|
66
|
-
|
64
|
+
- 0
|
65
|
+
- 0
|
66
|
+
- 2
|
67
|
+
version: 0.0.2
|
67
68
|
type: :runtime
|
68
69
|
version_requirements: *id003
|
69
70
|
- !ruby/object:Gem::Dependency
|
@@ -87,7 +88,7 @@ dependencies:
|
|
87
88
|
requirement: &id005 !ruby/object:Gem::Requirement
|
88
89
|
none: false
|
89
90
|
requirements:
|
90
|
-
- -
|
91
|
+
- - ">="
|
91
92
|
- !ruby/object:Gem::Version
|
92
93
|
hash: 25
|
93
94
|
segments:
|
@@ -96,14 +97,9 @@ dependencies:
|
|
96
97
|
version: "0.9"
|
97
98
|
type: :development
|
98
99
|
version_requirements: *id005
|
99
|
-
description:
|
100
|
-
|
101
|
-
|
102
|
-
Rocket provides also JavaScript toolkit to serve up instructions to clients, and
|
103
|
-
ruby library which handles events triggering. This Project was strongly inspired
|
104
|
-
by awesome PusherApp.
|
105
|
-
|
106
|
-
email: chris@nu7hat.ch
|
100
|
+
description: Rocket is a very fast and reliable web socket server built upon em-websockets library. Rocket provides also JavaScript toolkit to serve up instructions to clients, and ruby library which handles events triggering. This Project was strongly inspired by awesome PusherApp.
|
101
|
+
email:
|
102
|
+
- chris@nu7hat.ch
|
107
103
|
executables: []
|
108
104
|
|
109
105
|
extensions: []
|
@@ -116,24 +112,16 @@ files:
|
|
116
112
|
- LICENSE
|
117
113
|
- README.md
|
118
114
|
- Rakefile
|
119
|
-
- bin/rocket
|
120
115
|
- lib/rocket.rb
|
121
|
-
- lib/rocket/channel.rb
|
122
|
-
- lib/rocket/client.rb
|
123
|
-
- lib/rocket/helpers.rb
|
124
116
|
- lib/rocket/version.rb
|
125
|
-
- lib/rocket/websocket.rb
|
126
117
|
- rocket.gemspec
|
127
|
-
- spec/helpers_spec.rb
|
128
|
-
- spec/rocket_spec.rb
|
129
|
-
- spec/spec_helper.rb
|
130
118
|
has_rdoc: true
|
131
119
|
homepage: http://github.com/araneo/rocket
|
132
120
|
licenses: []
|
133
121
|
|
134
122
|
post_install_message:
|
135
|
-
rdoc_options:
|
136
|
-
|
123
|
+
rdoc_options: []
|
124
|
+
|
137
125
|
require_paths:
|
138
126
|
- lib
|
139
127
|
required_ruby_version: !ruby/object:Gem::Requirement
|
data/bin/rocket
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
data/lib/rocket/channel.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
3
|
-
module Rocket
|
4
|
-
class Channel
|
5
|
-
|
6
|
-
attr_reader :client
|
7
|
-
|
8
|
-
def initialize(client, channel)
|
9
|
-
@client = client
|
10
|
-
@channel = channel
|
11
|
-
end
|
12
|
-
|
13
|
-
def trigger(event, data)
|
14
|
-
client.connection do |socket|
|
15
|
-
socket.send({ :event => event, :channel => channel, :data => data }.to_json)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
end # Channel
|
20
|
-
end # Rocket
|
data/lib/rocket/client.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
3
|
-
module Rocket
|
4
|
-
# This Rocket client allows for triggering events via Rocket server.
|
5
|
-
#
|
6
|
-
# rocket = Rocket::Client.new("ws://host.com:9772", "my-app", "my53cr37k3y")
|
7
|
-
# rocket['my-channel'].trigger('event', { :hello => :world })
|
8
|
-
#
|
9
|
-
class Client
|
10
|
-
|
11
|
-
attr_reader :url
|
12
|
-
attr_reader :app_id
|
13
|
-
attr_reader :secret
|
14
|
-
|
15
|
-
def initialize(url, app_id, secret)
|
16
|
-
@url = File.join(url, 'app', app_id) + '?secret=' + secret
|
17
|
-
@app_id = app_id
|
18
|
-
end
|
19
|
-
|
20
|
-
def connection(&block)
|
21
|
-
socket = WebSocket.new(url)
|
22
|
-
yield(socket)
|
23
|
-
socket.close if socket && !socket.tcp_socket.closed?
|
24
|
-
end
|
25
|
-
|
26
|
-
def [](channel)
|
27
|
-
Channel.new(self, channel)
|
28
|
-
end
|
29
|
-
|
30
|
-
end # Client
|
31
|
-
end # Rocket
|
data/lib/rocket/helpers.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
module Rocket
|
2
|
-
module Helpers
|
3
|
-
|
4
|
-
# Hash given, returns it version with symbolized keys.
|
5
|
-
#
|
6
|
-
# p symbolize_keys("hello" => "world", ["Array here"] => "yup")
|
7
|
-
# p symbolize_keys(:one => 1, "two" => 2)
|
8
|
-
#
|
9
|
-
# produces:
|
10
|
-
#
|
11
|
-
# {:hello => "world", ["Array here"] => "yup"}
|
12
|
-
# {:one => 1, :two => 2}
|
13
|
-
#
|
14
|
-
def symbolize_keys(hash)
|
15
|
-
return hash unless hash.is_a?(Hash)
|
16
|
-
hash.inject({}) do |options, (key, value)|
|
17
|
-
options[(key.to_sym if key.respond_to?(:to_sym)) || key] = value
|
18
|
-
options
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
end # Helpers
|
23
|
-
end # Rocket
|
data/lib/rocket/websocket.rb
DELETED
@@ -1,225 +0,0 @@
|
|
1
|
-
# Copyright: Hiroshi Ichikawa <http://gimite.net/en/>
|
2
|
-
# Lincense: New BSD Lincense
|
3
|
-
# Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol
|
4
|
-
|
5
|
-
require "socket"
|
6
|
-
require "uri"
|
7
|
-
require "digest/md5"
|
8
|
-
require "openssl"
|
9
|
-
|
10
|
-
module Rocket
|
11
|
-
class WebSocket
|
12
|
-
|
13
|
-
class Error < RuntimeError; end
|
14
|
-
|
15
|
-
class << self
|
16
|
-
attr_accessor :debug
|
17
|
-
end
|
18
|
-
|
19
|
-
attr_reader :header
|
20
|
-
attr_reader :path
|
21
|
-
|
22
|
-
def initialize(arg, params = {})
|
23
|
-
uri = arg.is_a?(String) ? URI.parse(arg) : arg
|
24
|
-
|
25
|
-
if uri.scheme == "ws"
|
26
|
-
default_port = 80
|
27
|
-
elsif uri.scheme = "wss"
|
28
|
-
default_port = 443
|
29
|
-
else
|
30
|
-
raise(WebSocket::Error, "unsupported scheme: #{uri.scheme}")
|
31
|
-
end
|
32
|
-
|
33
|
-
@path = (uri.path.empty? ? "/" : uri.path) + (uri.query ? "?" + uri.query : "")
|
34
|
-
host = uri.host + (uri.port == default_port ? "" : ":#{uri.port}")
|
35
|
-
origin = params[:origin] || "http://#{uri.host}"
|
36
|
-
key1 = generate_key()
|
37
|
-
key2 = generate_key()
|
38
|
-
key3 = generate_key3()
|
39
|
-
|
40
|
-
socket = TCPSocket.new(uri.host, uri.port || default_port)
|
41
|
-
|
42
|
-
if uri.scheme == "ws"
|
43
|
-
@socket = socket
|
44
|
-
else
|
45
|
-
@socket = ssl_handshake(socket)
|
46
|
-
end
|
47
|
-
|
48
|
-
write(
|
49
|
-
"GET #{@path} HTTP/1.1\r\n" +
|
50
|
-
"Upgrade: WebSocket\r\n" +
|
51
|
-
"Connection: Upgrade\r\n" +
|
52
|
-
"Host: #{host}\r\n" +
|
53
|
-
"Origin: #{origin}\r\n" +
|
54
|
-
"Sec-WebSocket-Key1: #{key1}\r\n" +
|
55
|
-
"Sec-WebSocket-Key2: #{key2}\r\n" +
|
56
|
-
"\r\n" +
|
57
|
-
"#{key3}")
|
58
|
-
flush()
|
59
|
-
|
60
|
-
line = gets().chomp()
|
61
|
-
raise(WebSocket::Error, "bad response: #{line}") if !(line =~ /\AHTTP\/1.1 101 /n)
|
62
|
-
read_header()
|
63
|
-
if @header["Sec-WebSocket-Origin"] != origin
|
64
|
-
raise(WebSocket::Error,
|
65
|
-
"origin doesn't match: '#{@header["WebSocket-Origin"]}' != '#{origin}'")
|
66
|
-
end
|
67
|
-
reply_digest = read(16)
|
68
|
-
expected_digest = security_digest(key1, key2, key3)
|
69
|
-
if reply_digest != expected_digest
|
70
|
-
raise(WebSocket::Error,
|
71
|
-
"security digest doesn't match: %p != %p" % [reply_digest, expected_digest])
|
72
|
-
end
|
73
|
-
@handshaked = true
|
74
|
-
@closing_started = false
|
75
|
-
end
|
76
|
-
|
77
|
-
def send(data)
|
78
|
-
if !@handshaked
|
79
|
-
raise(WebSocket::Error, "call WebSocket\#handshake first")
|
80
|
-
end
|
81
|
-
data = force_encoding(data.dup(), "ASCII-8BIT")
|
82
|
-
write("\x00#{data}\xff")
|
83
|
-
flush()
|
84
|
-
end
|
85
|
-
|
86
|
-
def receive()
|
87
|
-
if !@handshaked
|
88
|
-
raise(WebSocket::Error, "call WebSocket\#handshake first")
|
89
|
-
end
|
90
|
-
packet = gets("\xff")
|
91
|
-
return nil if !packet
|
92
|
-
if packet =~ /\A\x00(.*)\xff\z/nm
|
93
|
-
return force_encoding($1, "UTF-8")
|
94
|
-
elsif packet == "\xff" && read(1) == "\x00" # closing
|
95
|
-
if @server
|
96
|
-
@socket.close()
|
97
|
-
else
|
98
|
-
close()
|
99
|
-
end
|
100
|
-
return nil
|
101
|
-
else
|
102
|
-
raise(WebSocket::Error, "input must be either '\\x00...\\xff' or '\\xff\\x00'")
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def tcp_socket
|
107
|
-
return @socket
|
108
|
-
end
|
109
|
-
|
110
|
-
def host
|
111
|
-
return @header["Host"]
|
112
|
-
end
|
113
|
-
|
114
|
-
def origin
|
115
|
-
return @header["Origin"]
|
116
|
-
end
|
117
|
-
|
118
|
-
# Does closing handshake.
|
119
|
-
def close()
|
120
|
-
return if @closing_started
|
121
|
-
write("\xff\x00")
|
122
|
-
@socket.close() if !@server
|
123
|
-
@closing_started = true
|
124
|
-
end
|
125
|
-
|
126
|
-
def close_socket()
|
127
|
-
@socket.close()
|
128
|
-
end
|
129
|
-
|
130
|
-
private
|
131
|
-
|
132
|
-
NOISE_CHARS = ("\x21".."\x2f").to_a() + ("\x3a".."\x7e").to_a()
|
133
|
-
|
134
|
-
def read_header()
|
135
|
-
@header = {}
|
136
|
-
while line = gets()
|
137
|
-
line = line.chomp()
|
138
|
-
break if line.empty?
|
139
|
-
if !(line =~ /\A(\S+): (.*)\z/n)
|
140
|
-
raise(WebSocket::Error, "invalid request: #{line}")
|
141
|
-
end
|
142
|
-
@header[$1] = $2
|
143
|
-
end
|
144
|
-
if @header["Upgrade"] != "WebSocket"
|
145
|
-
raise(WebSocket::Error, "invalid Upgrade: " + @header["Upgrade"])
|
146
|
-
end
|
147
|
-
if @header["Connection"] != "Upgrade"
|
148
|
-
raise(WebSocket::Error, "invalid Connection: " + @header["Connection"])
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
def gets(rs = $/)
|
153
|
-
line = @socket.gets(rs)
|
154
|
-
$stderr.printf("recv> %p\n", line) if WebSocket.debug
|
155
|
-
return line
|
156
|
-
end
|
157
|
-
|
158
|
-
def read(num_bytes)
|
159
|
-
str = @socket.read(num_bytes)
|
160
|
-
$stderr.printf("recv> %p\n", str) if WebSocket.debug
|
161
|
-
return str
|
162
|
-
end
|
163
|
-
|
164
|
-
def write(data)
|
165
|
-
if WebSocket.debug
|
166
|
-
data.scan(/\G(.*?(\n|\z))/n) do
|
167
|
-
$stderr.printf("send> %p\n", $&) if !$&.empty?
|
168
|
-
end
|
169
|
-
end
|
170
|
-
@socket.write(data)
|
171
|
-
end
|
172
|
-
|
173
|
-
def flush()
|
174
|
-
@socket.flush()
|
175
|
-
end
|
176
|
-
|
177
|
-
def security_digest(key1, key2, key3)
|
178
|
-
bytes1 = websocket_key_to_bytes(key1)
|
179
|
-
bytes2 = websocket_key_to_bytes(key2)
|
180
|
-
return Digest::MD5.digest(bytes1 + bytes2 + key3)
|
181
|
-
end
|
182
|
-
|
183
|
-
def generate_key()
|
184
|
-
spaces = 1 + rand(12)
|
185
|
-
max = 0xffffffff / spaces
|
186
|
-
number = rand(max + 1)
|
187
|
-
key = (number * spaces).to_s()
|
188
|
-
(1 + rand(12)).times() do
|
189
|
-
char = NOISE_CHARS[rand(NOISE_CHARS.size)]
|
190
|
-
pos = rand(key.size + 1)
|
191
|
-
key[pos...pos] = char
|
192
|
-
end
|
193
|
-
spaces.times() do
|
194
|
-
pos = 1 + rand(key.size - 1)
|
195
|
-
key[pos...pos] = " "
|
196
|
-
end
|
197
|
-
return key
|
198
|
-
end
|
199
|
-
|
200
|
-
def generate_key3()
|
201
|
-
return [rand(0x100000000)].pack("N") + [rand(0x100000000)].pack("N")
|
202
|
-
end
|
203
|
-
|
204
|
-
def websocket_key_to_bytes(key)
|
205
|
-
num = key.gsub(/[^\d]/n, "").to_i() / key.scan(/ /).size
|
206
|
-
return [num].pack("N")
|
207
|
-
end
|
208
|
-
|
209
|
-
def force_encoding(str, encoding)
|
210
|
-
if str.respond_to?(:force_encoding)
|
211
|
-
return str.force_encoding(encoding)
|
212
|
-
else
|
213
|
-
return str
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
def ssl_handshake(socket)
|
218
|
-
ssl_context = OpenSSL::SSL::SSLContext.new()
|
219
|
-
ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_context)
|
220
|
-
ssl_socket.sync_close = true
|
221
|
-
ssl_socket.connect()
|
222
|
-
return ssl_socket
|
223
|
-
end
|
224
|
-
end # WebSocket
|
225
|
-
end # Rocket
|
data/spec/helpers_spec.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require File.expand_path("../spec_helper", __FILE__)
|
2
|
-
|
3
|
-
class HelpersPoweredClass
|
4
|
-
include Rocket::Helpers
|
5
|
-
end
|
6
|
-
|
7
|
-
describe Rocket::Helpers do
|
8
|
-
subject do
|
9
|
-
HelpersPoweredClass.new
|
10
|
-
end
|
11
|
-
|
12
|
-
describe "#symbolize_keys" do
|
13
|
-
it "should return given object when it's not a Hash" do
|
14
|
-
subject.symbolize_keys(obj = Object.new).should == obj
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should symbolize given hash keys" do
|
18
|
-
subject.symbolize_keys({"hello" => "world"}).should == {:hello => "world"}
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
data/spec/rocket_spec.rb
DELETED