sockjs 0.2.1 → 0.3.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b9ba7f7379bb54e6043eec61b16e3e88ee48d2f0
4
+ data.tar.gz: ec3beafcaf422d4d4641360dd8e0e2f3e4512f5b
5
+ SHA512:
6
+ metadata.gz: b4aed2c1dfa3b3d00cecf86de2815a3a26914c96812132c786d55f00b4782ceffc108e0428310060ad7525e0809a8273dff252f4ef4b36db0f9b0273afa45fdb
7
+ data.tar.gz: ef0f4e03c5dbf912e5ae0988fb308ffa749e2857679cbd810048f7da05bd121ddedda54b60b8655ba786e2b1a1636cf588c57cfffeb53fc25c867949f07fe3f7
data/LICENCE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (C) 2011 VMware, Inc.
1
+ Copyright (C) 2011 Judson Lester and VMware, Inc.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
@@ -1,16 +1,28 @@
1
1
  h1. About
2
2
 
3
3
  _*Disclaimer:* This library is still work in progress._
4
+ (It is coming together though)
4
5
 
5
- SockJS is WebSocket emulation library. It means that you use the WebSocket API, only instead of @WebSocket@ class you instantiate @SockJS@ class. I highly recommend to read "SockJS: WebSocket emulation":http://www.rabbitmq.com/blog/2011/09/13/sockjs-websocket-emulation on the RabbitMQ blog for more info.
6
+ SockJS is WebSocket emulation library. It means that you use the WebSocket API,
7
+ only instead of @WebSocket@ class you instantiate @SockJS@ class. I highly
8
+ recommend to read "SockJS: WebSocket
9
+ emulation":http://www.rabbitmq.com/blog/2011/09/13/sockjs-websocket-emulation
10
+ on the RabbitMQ blog for more info.
6
11
 
7
12
  h2. Prerequisites
8
13
 
9
- Even though this library uses Rack interface, *Thin is required* as "it supports asynchronous callback":http://macournoyer.com/blog/2009/06/04/pusher-and-async-with-thin. For Websockets, we use "faye-websocket":http://blog.jcoglan.com/2011/11/28/announcing-faye-websocket-a-standards-compliant-websocket-library gem.
14
+ Even though this library uses Rack interface, *Thin is required* as "it
15
+ supports asynchronous
16
+ callback":http://macournoyer.com/blog/2009/06/04/pusher-and-async-with-thin.
17
+ For Websockets, we use
18
+ "faye-websocket":http://blog.jcoglan.com/2011/11/28/announcing-faye-websocket-a-standards-compliant-websocket-library
19
+ gem.
10
20
 
11
21
  h2. The Client-Side Part
12
22
 
13
- For the client-side part you have to use JS library "sockjs-client":http://sockjs.github.com/sockjs-client which provides WebSocket-like API. Here's an example:
23
+ For the client-side part you have to use JS library
24
+ "sockjs-client":http://sockjs.github.com/sockjs-client which provides
25
+ WebSocket-like API. Here's an example:
14
26
 
15
27
  <pre>
16
28
  <script src="http://cdn.sockjs.org/sockjs-0.2.1.min.js"></script>
@@ -116,3 +128,8 @@ h1. Links
116
128
  * "SockJS: WebSocket emulation":http://www.rabbitmq.com/blog/2011/09/13/sockjs-websocket-emulation
117
129
  * "SockJS: web messaging ain't easy":http://www.rabbitmq.com/blog/2011/08/22/sockjs-web-messaging-aint-easy
118
130
  * "PubSubHuddle Realtime Web talk":http://www.rabbitmq.com/blog/2011/09/26/pubsubhuddle-realtime-web-talk
131
+
132
+ h1. Contributors
133
+
134
+ * Judson Lester ( @nyarly )
135
+ * Kacper Kawecki ( @kacperk )
@@ -1,5 +1,3 @@
1
-
2
-
3
1
  module MetaState
4
2
  class Error < ::StandardError; end
5
3
  class WrongStateError < Error; end
@@ -71,9 +69,9 @@ module MetaState
71
69
  @void_state_module = Module.new do
72
70
  methods.each do |method|
73
71
  if NON_MESSAGES.include?(method)
74
- define_method(method){}
72
+ define_method(method){|*args| }
75
73
  else
76
- define_method(method) do
74
+ define_method(method) do |*args|
77
75
  raise WrongStateError, "Message #{method} received in state #{current_state}"
78
76
  end
79
77
  end
@@ -134,6 +132,9 @@ module MetaState
134
132
  return true if target_state == current_state
135
133
  source_state = current_state
136
134
 
135
+ if target_state == SockJS::Session::Closed
136
+ debug{ caller }
137
+ end
137
138
  debug{ "Transitioning from #{source_state.inspect} to #{target_state.inspect}" }
138
139
 
139
140
  on_exit
@@ -47,7 +47,7 @@ module Rack
47
47
  class SockJS
48
48
  SERVER_SESSION_REGEXP = %r{/([^/]*)/([^/]*)}
49
49
  DEFAULT_OPTIONS = {
50
- :sockjs_url => "http://cdn.sockjs.org/sockjs-#{::SockJS::PROTOCOL_VERSION}.min.js"
50
+ :sockjs_url => "http://cdn.sockjs.org/sockjs-#{::SockJS::PROTOCOL_VERSION_STRING}.min.js"
51
51
  }
52
52
 
53
53
 
@@ -2,14 +2,17 @@
2
2
 
3
3
  require "faye/websocket"
4
4
 
5
+ if defined? Thin
6
+ Faye::WebSocket.load_adapter('thin')
7
+ end
8
+ if defined? Rainbows
9
+ Faye::WebSocket.load_adapter('rainbows')
10
+ end
11
+ if defined? Goliath
12
+ Faye::WebSocket.load_adapter('goliath')
13
+ end
14
+
5
15
  class Thin::Request
6
16
  WEBSOCKET_RECEIVE_CALLBACK = 'websocket.receive_callback'.freeze
7
17
  GET = 'GET'.freeze
8
-
9
- def websocket?
10
- @env['REQUEST_METHOD'] == GET and
11
- @env['HTTP_CONNECTION'] and
12
- @env['HTTP_CONNECTION'].split(/\s*,\s*/).include?('Upgrade') and
13
- ['WebSocket', 'websocket'].include?(@env['HTTP_UPGRADE'])
14
- end
15
18
  end
@@ -82,7 +82,7 @@ module SockJS
82
82
 
83
83
 
84
84
  class ClosingFrame < Frame
85
- def initialize(status, message)
85
+ def initialize(status=1000, message="Normal closing")
86
86
  validate Integer, status
87
87
  validate String, message
88
88
 
@@ -109,6 +109,7 @@ module SockJS
109
109
  end
110
110
 
111
111
  def origin
112
+ return "*" if self.headers["origin"] == "null"
112
113
  self.headers["origin"] || "*"
113
114
  end
114
115
 
@@ -109,6 +109,7 @@ module SockJS
109
109
  def set_access_control(origin)
110
110
  self.set_header("Access-Control-Allow-Origin", origin)
111
111
  self.set_header("Access-Control-Allow-Credentials", "true")
112
+ self.set_header("Access-Control-Allow-Headers", "Content-Type Origin Accept X-Requested-With X-CSRF-Token If-Modified-Since If-None-Match Auth-User-Token Authorization Connection Cookie User-Agent")
112
113
  end
113
114
 
114
115
  def set_cache_control
@@ -15,7 +15,13 @@ module SockJS
15
15
 
16
16
  #Close the *response* not the *session*
17
17
  def disconnect
18
- @response.finish
18
+ #WEBSOCKET shouldn't have limit of data - faye will send closing frame
19
+ #after 1GB
20
+ if @transport.kind_of?(SockJS::Transports::WebSocket)
21
+ @total_sent_length = 0
22
+ return
23
+ end
24
+ @response.finish if @response.respond_to?(:finish)
19
25
  end
20
26
 
21
27
  def heartbeat
@@ -55,7 +61,9 @@ module SockJS
55
61
 
56
62
  def attach_consumer(response, transport)
57
63
  @consumer = Consumer.new(response, transport)
64
+ activate
58
65
  transition_to :attached
66
+ after_consumer_attached
59
67
  end
60
68
 
61
69
  def detach_consumer
@@ -63,6 +71,12 @@ module SockJS
63
71
  close(1002,"Connection interrupted")
64
72
  end
65
73
 
74
+ def activate
75
+ end
76
+
77
+ def suspended
78
+ end
79
+
66
80
  def send(*messages)
67
81
  @outbox += messages
68
82
  end
@@ -72,6 +86,10 @@ module SockJS
72
86
  @close_message = message
73
87
  transition_to(:closed)
74
88
  end
89
+
90
+ def set_heartbeat_timer
91
+ _set_heartbeat_timer
92
+ end
75
93
  end
76
94
 
77
95
  state :Attached do
@@ -91,6 +109,7 @@ module SockJS
91
109
 
92
110
  def detach_consumer
93
111
  transition_to :detached
112
+ after_consumer_detached
94
113
  end
95
114
 
96
115
  def send(*messages)
@@ -102,13 +121,72 @@ module SockJS
102
121
  @consumer.heartbeat
103
122
  end
104
123
 
105
- def close(status = nil, message = nil)
124
+ def suspend
125
+ transition_to :suspended
126
+ end
127
+
128
+ def activate
129
+ end
130
+
131
+ def close(status = 1002, message = "Connection interrupted")
132
+ @close_status = status
133
+ @close_message = message
134
+ @consumer.closing(@close_status, @close_message)
135
+ @consumer = nil
136
+ transition_to(:closed)
137
+ end
138
+
139
+ def set_heartbeat_timer
140
+ _set_heartbeat_timer
141
+ end
142
+ end
143
+
144
+ state :Suspended do
145
+ def on_enter
146
+ SockJS.debug "Session suspended - it is on hold"
147
+ suspended
148
+ end
149
+
150
+ def attach_consumer(response, transport)
151
+ SockJS.debug "Session#attach_consumer: another connection still open"
152
+ transport.closing_frame(response, 2010, "Another connection still open")
153
+ close(1002, "Connection interrupted")
154
+ end
155
+
156
+ def detach_consumer
157
+ transition_to :detached
158
+ after_consumer_detached
159
+ end
160
+
161
+ def send(*messages)
162
+ @outbox += messages
163
+ end
164
+
165
+ def send_heartbeat
166
+ @consumer.heartbeat
167
+ end
168
+
169
+ def suspend
170
+ end
171
+
172
+ def activate
173
+ SockJS.debug "Session activated - is not on hold anymore!"
174
+ transition_to :attached
175
+ activated
176
+ end
177
+
178
+
179
+ def close(status = 1002, message = "Connection interrupted")
106
180
  @close_status = status
107
181
  @close_message = message
108
182
  @consumer.closing(@close_status, @close_message)
109
183
  @consumer = nil
110
184
  transition_to(:closed)
111
185
  end
186
+
187
+ def set_heartbeat_timer
188
+ _set_heartbeat_timer
189
+ end
112
190
  end
113
191
 
114
192
  state :Closed do
@@ -117,11 +195,28 @@ module SockJS
117
195
  @close_message ||= "Go away!"
118
196
  clear_all_timers
119
197
  set_close_timer
198
+ closed
199
+ end
200
+
201
+ def suspend
202
+ SockJS.debug "Session#suspend: connection closed!"
203
+ end
204
+
205
+ def activate
206
+ SockJS.debug "Session#activate: connection closed!"
120
207
  end
121
208
 
122
209
  def attach_consumer(response, transport)
123
210
  transport.closing_frame(response, @close_status, @close_message)
124
211
  end
212
+
213
+ def close(status=nil, message=nil)
214
+ #can be called from faye onclose hook
215
+ end
216
+
217
+ def set_heartbeat_timer
218
+ SockJS.debug "trying to setup heartbeat on closed session!"
219
+ end
125
220
  end
126
221
 
127
222
 
@@ -132,6 +227,7 @@ module SockJS
132
227
  # of json-encoded messages, depending on transport.
133
228
  def receive_message(data)
134
229
  clear_timer(:disconnect)
230
+ activate
135
231
 
136
232
  SockJS.debug "Session receiving message: #{data.inspect}"
137
233
  messages = parse_json(data)
@@ -151,6 +247,7 @@ module SockJS
151
247
  if @consumer.total_sent_length >= max_permitted_content_length
152
248
  SockJS.debug "Maximum content length exceeded, closing the connection."
153
249
 
250
+ #shouldn't be restarting connection?
154
251
  @consumer.disconnect
155
252
  else
156
253
  SockJS.debug "Permitted content length: #{@consumer.total_sent_length} of #{max_permitted_content_length}"
@@ -159,7 +256,7 @@ module SockJS
159
256
 
160
257
  def run_user_app
161
258
  unless @received_messages.empty?
162
- reset_heartbeat_timer
259
+ reset_heartbeat_timer #XXX Only one point which can set heartbeat while state is closed
163
260
 
164
261
  SockJS.debug "Executing user's SockJS app"
165
262
 
@@ -188,6 +285,20 @@ module SockJS
188
285
  def after_app_run
189
286
  end
190
287
 
288
+ def closed
289
+ end
290
+
291
+ def activated
292
+ end
293
+
294
+ def suspended
295
+ end
296
+
297
+ def after_consumer_attached
298
+ end
299
+
300
+ def after_consumer_detached
301
+ end
191
302
 
192
303
  attr_accessor :disconnect_delay, :interval
193
304
  attr_reader :transport, :response, :outbox, :closing_frame, :data
@@ -231,7 +342,7 @@ module SockJS
231
342
  end
232
343
 
233
344
  JSON.parse("[#{data}]")[0]
234
- rescue JSON::ParserError => error
345
+ rescue JSON::ParserError
235
346
  raise SockJS::InvalidJSON.new(500, "Broken JSON encoding.")
236
347
  end
237
348
 
@@ -250,17 +361,17 @@ module SockJS
250
361
  def disconnect_expired
251
362
  SockJS.debug "#{@disconnect_delay} has passed, firing @disconnect_timer"
252
363
  close
364
+ #XXX Shouldn't destroy the session?
253
365
  end
254
366
 
255
- #XXX Remove? What's this for?
256
367
  def check_response_alive
257
368
  if @consumer
258
369
  begin
259
370
  @consumer.check_alive
260
371
  rescue Exception => error
261
- puts "==> "
372
+ puts "==> #{error.message}"
262
373
  SockJS.debug error
263
- puts "==> "
374
+ puts "==> #{error.message}"
264
375
  on_close
265
376
  @alive_checker.cancel
266
377
  end
@@ -316,7 +427,7 @@ module SockJS
316
427
  set_alive_timer
317
428
  end
318
429
 
319
- def set_heartbeat_timer
430
+ def _set_heartbeat_timer
320
431
  clear_timer(:disconnect)
321
432
  clear_timer(:alive)
322
433
  set_timer(:heartbeat, EM::PeriodicTimer, 25) do
@@ -127,7 +127,12 @@ module SockJS
127
127
  "#{payload}\n"
128
128
  end
129
129
 
130
+ #How is this used?
131
+ #Thread safety?
132
+ attr_reader :remote_addr, :http_origin
130
133
  def call(env)
134
+ @remote_addr = env["REMOTE_ADDR"]
135
+ @http_origin = env["HTTP_ORIGIN"]
131
136
  SockJS.debug "Request for #{self.class}: #{env["REQUEST_METHOD"]}/#{env["PATH_INFO"]}"
132
137
  request = ::SockJS::Request.new(env)
133
138
  EM.next_tick do
@@ -41,6 +41,10 @@ module SockJS
41
41
  raise SockJS::HttpError.new(500, '"callback" parameter required')
42
42
  end
43
43
 
44
+ if !!/[^a-zA-Z0-9\-_.]/.match(response.request.callback)
45
+ raise SockJS::HttpError.new(500, 'invalid "callback" parameter')
46
+ end
47
+
44
48
  super
45
49
  end
46
50
 
@@ -28,6 +28,7 @@ module SockJS
28
28
  EOB
29
29
 
30
30
  def setup_response(request, response)
31
+ SockJS.debug("body: #{@body.inspect}")
31
32
  response.status = 200
32
33
  response.set_header("ETag", self.etag)
33
34
  response.set_cache_control
@@ -49,7 +50,6 @@ module SockJS
49
50
  # Handler.
50
51
  def handle_request(request)
51
52
  if request.fresh?(etag)
52
- SockJS.debug "Content hasn't been modified."
53
53
  response = build_response(request)
54
54
  response.status = 304
55
55
  response.finish
@@ -1,5 +1,12 @@
1
1
  # encoding: utf-8
2
2
 
3
+ =begin
4
+ #XXX
5
+ #kacperk added this:
6
+ def activate
7
+ end# encoding: utf-8
8
+ =end
9
+
3
10
  require "forwardable"
4
11
  require "sockjs/faye"
5
12
  require "sockjs/transport"
@@ -61,8 +68,10 @@ module SockJS
61
68
  if not @options[:websocket]
62
69
  raise HttpError.new(404, "WebSockets Are Disabled")
63
70
  elsif request.env["HTTP_UPGRADE"].to_s.downcase != "websocket"
71
+ SockJS.debug("Wrong headers! HTTP_UPGRADE = #{request.env["HTTP_UPGRADE"].to_s}")
64
72
  raise HttpError.new(400, 'Can "Upgrade" only to "WebSocket".')
65
73
  elsif not ["Upgrade", "keep-alive, Upgrade"].include?(request.env["HTTP_CONNECTION"])
74
+ SockJS.debug("Wrong headers! HTTP_CONNECTION = #{request.env["HTTP_CONNECTION"].to_s}")
66
75
  raise HttpError.new(400, '"Connection" must be "Upgrade".')
67
76
  end
68
77
 
@@ -85,16 +94,17 @@ module SockJS
85
94
 
86
95
  def process_session(session, web_socket)
87
96
  #XXX Facade around websocket?
88
-
89
- web_socket.onopen = lambda do |event|
97
+ @session = session
98
+ web_socket.on :open do |event|
90
99
  begin
100
+ SockJS.debug "Attaching consumer"
91
101
  session.attach_consumer(web_socket, self)
92
102
  rescue Object => ex
93
103
  SockJS::debug "Error opening (#{event.inspect[0..40]}) websocket: #{ex.inspect}"
94
104
  end
95
105
  end
96
106
 
97
- web_socket.onmessage = lambda do |event|
107
+ web_socket.on :message do |event|
98
108
  begin
99
109
  session.receive_message(extract_message(event))
100
110
  rescue Object => ex
@@ -103,11 +113,11 @@ module SockJS
103
113
  end
104
114
  end
105
115
 
106
- web_socket.onclose = lambda do |event|
116
+ web_socket.on :close do |event|
107
117
  begin
108
- session.close
118
+ session.close(1000, "Session finished")
109
119
  rescue Object => ex
110
- SockJS::debug "Error closing websocket (#{event.inspect[0..40]}): #{ex.inspect}"
120
+ SockJS::debug "Error closing websocket (#{event.inspect[0..40]}): #{ex.inspect} \n#{ex.message} \n#{ex.backtrace.join("\n")}"
111
121
  end
112
122
  end
113
123
  end
@@ -122,6 +132,7 @@ module SockJS
122
132
  end
123
133
 
124
134
  def finish_response(web_socket)
135
+ SockJS.debug "Finishing response"
125
136
  web_socket.close
126
137
  end
127
138
 
@@ -129,11 +140,36 @@ module SockJS
129
140
  SockJS.debug "Received message event: #{event.data.inspect}"
130
141
  event.data
131
142
  end
143
+
144
+ def heartbeat_frame(web_socket)
145
+ @pong = true if @pong.nil?
146
+
147
+ #no replay from last connection - susspend session
148
+ if !@pong
149
+ @session.suspend if @session
150
+ end
151
+ @pong = false
152
+ web_socket.ping("ping") do
153
+ SockJS.debug "pong"
154
+ @pong = true
155
+ @session.activate
156
+ end
157
+ super
158
+ end
132
159
  end
133
160
 
134
161
  class RawWebSocket < WebSocket
135
162
  register 'GET', 'websocket'
136
163
 
164
+ def handle_request(request)
165
+ ver = request.env["sec-websocket-version"] || ""
166
+ unless ['8', '13'].include?(ver)
167
+ raise HttpError.new(400, 'Only supported WebSocket protocol is RFC 6455.')
168
+ end
169
+
170
+ super
171
+ end
172
+
137
173
  def self.routing_prefix
138
174
  "/" + self.prefix
139
175
  end
@@ -2,12 +2,12 @@
2
2
 
3
3
  module SockJS
4
4
  # SockJS protocol version.
5
- PROTOCOL_VERSION = [0, 2, 1]
5
+ PROTOCOL_VERSION = [0, 3, 4]
6
6
 
7
7
  PROTOCOL_VERSION_STRING = PROTOCOL_VERSION.join(".")
8
8
 
9
9
  # Patch version of the gem.
10
- PATCH_VERSION = []
10
+ PATCH_VERSION = [0]
11
11
 
12
12
  GEM_VERSION = (PROTOCOL_VERSION + PATCH_VERSION).join(".")
13
13
  end
@@ -40,7 +40,7 @@ describe SockJS::Transport do
40
40
  end
41
41
 
42
42
  let :session do
43
- mock("Session")
43
+ double("Session")
44
44
  end
45
45
 
46
46
  describe "#format_frame(payload)" do
@@ -17,11 +17,11 @@ module TransportSpecMacros
17
17
  describe SockJS::Transport do
18
18
  describe "transports[#{path}]" do
19
19
  let :route_set do
20
- mock("Route Set")
20
+ double("Route Set")
21
21
  end
22
22
 
23
23
  let :connection do
24
- mock("Connection")
24
+ double("Connection")
25
25
  end
26
26
 
27
27
  let :options do
@@ -105,7 +105,7 @@ class SockJS::Response
105
105
  end
106
106
 
107
107
  RSpec.configure do |config|
108
- config.backtrace_clean_patterns.delete(/gems/)
108
+ config.backtrace_exclusion_patterns.delete(/gems/)
109
109
  config.extend(TransportSpecMacros)
110
110
  config.before do
111
111
  class SockJS::Transport
metadata CHANGED
@@ -1,100 +1,87 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sockjs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
5
- prerelease:
4
+ version: 0.3.4.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Judson Lester
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-12-16 00:00:00.000000000 Z
11
+ date: 2014-07-24 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rack
16
- requirement: &76745750 !ruby/object:Gem::Requirement
17
- none: true
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *76745750
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
25
27
  - !ruby/object:Gem::Dependency
26
28
  name: thin
27
- requirement: &76744510 !ruby/object:Gem::Requirement
28
- none: true
29
+ requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ! '>='
31
+ - - '>='
31
32
  - !ruby/object:Gem::Version
32
33
  version: '0'
33
34
  type: :runtime
34
35
  prerelease: false
35
- version_requirements: *76744510
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
36
41
  - !ruby/object:Gem::Dependency
37
42
  name: json
38
- requirement: &76743770 !ruby/object:Gem::Requirement
39
- none: true
43
+ requirement: !ruby/object:Gem::Requirement
40
44
  requirements:
41
- - - ! '>='
45
+ - - '>='
42
46
  - !ruby/object:Gem::Version
43
47
  version: '0'
44
48
  type: :runtime
45
49
  prerelease: false
46
- version_requirements: *76743770
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
47
55
  - !ruby/object:Gem::Dependency
48
56
  name: faye-websocket
49
- requirement: &76742940 !ruby/object:Gem::Requirement
50
- none: false
57
+ requirement: !ruby/object:Gem::Requirement
51
58
  requirements:
52
59
  - - ~>
53
60
  - !ruby/object:Gem::Version
54
- version: 0.4.3
55
- segments:
56
- - 0
57
- - 4
58
- - 3
61
+ version: 0.7.1
59
62
  type: :runtime
60
63
  prerelease: false
61
- version_requirements: *76742940
62
- - !ruby/object:Gem::Dependency
63
- name: regin
64
- requirement: &76741840 !ruby/object:Gem::Requirement
65
- none: false
64
+ version_requirements: !ruby/object:Gem::Requirement
66
65
  requirements:
67
66
  - - ~>
68
67
  - !ruby/object:Gem::Version
69
- version: 0.3.8
70
- segments:
71
- - 0
72
- - 3
73
- - 8
74
- type: :runtime
75
- prerelease: false
76
- version_requirements: *76741840
68
+ version: 0.7.1
77
69
  - !ruby/object:Gem::Dependency
78
70
  name: rack-mount
79
- requirement: &76761770 !ruby/object:Gem::Requirement
80
- none: false
71
+ requirement: !ruby/object:Gem::Requirement
81
72
  requirements:
82
73
  - - ~>
83
74
  - !ruby/object:Gem::Version
84
75
  version: 0.8.3
85
- segments:
86
- - 0
87
- - 8
88
- - 3
89
76
  type: :runtime
90
77
  prerelease: false
91
- version_requirements: *76761770
92
- description: ! ' SockJS is a WebSocket emulation library. It means that you use
93
- the WebSocket API, only instead of WebSocket class you instantiate SockJS class.
94
- In absence of WebSocket, some of the fallback transports will be used. This code
95
- is compatible with SockJS protocol 0.2.1.
96
-
97
- '
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 0.8.3
83
+ description: |2
84
+ SockJS is a WebSocket emulation library. It means that you use the WebSocket API, only instead of WebSocket class you instantiate SockJS class. In absence of WebSocket, some of the fallback transports will be used. This code is compatible with SockJS protocol 0.3.4.
98
85
  email: nyarly@gmail.com
99
86
  executables: []
100
87
  extensions: []
@@ -143,29 +130,25 @@ files:
143
130
  - spec/support/async-test.rb
144
131
  homepage: https://github.com/nyarly/sockjs-ruby
145
132
  licenses: []
133
+ metadata: {}
146
134
  post_install_message:
147
135
  rdoc_options: []
148
136
  require_paths:
149
137
  - lib
150
138
  required_ruby_version: !ruby/object:Gem::Requirement
151
- none: false
152
139
  requirements:
153
- - - ~>
140
+ - - '>='
154
141
  - !ruby/object:Gem::Version
155
142
  version: '1.9'
156
143
  required_rubygems_version: !ruby/object:Gem::Requirement
157
- none: false
158
144
  requirements:
159
- - - ! '>='
145
+ - - '>='
160
146
  - !ruby/object:Gem::Version
161
147
  version: '0'
162
- segments:
163
- - 0
164
- hash: -1068506783
165
148
  requirements: []
166
149
  rubyforge_project: sockjs
167
- rubygems_version: 1.8.15
150
+ rubygems_version: 2.0.14
168
151
  signing_key:
169
- specification_version: 3
152
+ specification_version: 4
170
153
  summary: Ruby server for SockJS
171
154
  test_files: []