webmate 0.1.5 → 0.1.6

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.
@@ -37,6 +37,7 @@ require 'webmate/routes/handler'
37
37
 
38
38
  Bundler.require(:default, Webmate.env.to_sym)
39
39
 
40
+ require 'webmate/socket.io/request'
40
41
  require 'webmate/socket.io/actions/handshake'
41
42
  require 'webmate/socket.io/actions/connection'
42
43
  require 'webmate/socket.io/packets/base'
@@ -14,5 +14,19 @@ module Webmate::Responders
14
14
  def to_rack
15
15
  [@status, {}, @data]
16
16
  end
17
+
18
+ def to_packet
19
+ Webmate::SocketIO::Packets::Message.build_response_packet(self).to_packet
20
+ end
21
+
22
+ class << self
23
+ def build_not_found(message, options = {})
24
+ self.new(message, {status: 404}.merge(options))
25
+ end
26
+
27
+ def build_error(message, options = {})
28
+ self.new(message, {status: 500}.merge(options))
29
+ end
30
+ end
17
31
  end
18
32
  end
@@ -14,12 +14,10 @@ module Webmate::Routes
14
14
  end
15
15
 
16
16
  session_id = route_info[:params][:session_id]
17
- Webmate::Websockets.subscribe(session_id, request) do |message|
18
- if route_info = application.routes.match(message['method'], 'WS', message.path)
19
- request_info = params_from_websoket(route_info, message)
20
- # here we should create subscriber who can live
21
- # between messages.. but not between requests.
22
- route_info[:responder].new(request_info).respond
17
+ Webmate::Websockets.subscribe(session_id, request) do |request|
18
+ if route_info = application.routes.match(request[:method], 'WS', request.path)
19
+ request_info = prepare_response_params(route_info, request)
20
+ response = route_info[:responder].new(request_info).respond
23
21
  end
24
22
  end
25
23
 
@@ -28,18 +26,17 @@ module Webmate::Routes
28
26
  [-1, {}, []]
29
27
 
30
28
  else # HTTP
31
- # this should return correct Rack response..
32
- request_info = params_from_http(route_info)
29
+ request_info = prepare_response_params(route_info, request)
33
30
  response = route_info[:responder].new(request_info).respond
34
31
  response.to_rack
35
32
  end
36
33
  end
37
34
 
38
- # this method prepare data for responder from http request
35
+ # this method prepare data for responder from request
39
36
  # @param Hash request_info = { path: '/', metadata: {}, action: 'index', params: { test: true } }
40
- def params_from_http(route_info)
37
+ def prepare_response_params(route_info, request)
41
38
  # create unified request info
42
- request_params = http_body_request_params
39
+ request_params = request_params_all(request)
43
40
  metadata = request_params.delete(:metadata)
44
41
  {
45
42
  path: request.path,
@@ -50,25 +47,15 @@ module Webmate::Routes
50
47
  }
51
48
  end
52
49
 
53
- # this method prepare data for responder from http request
54
- def params_from_websoket(route_info, message)
55
- {
56
- path: message.path,
57
- metadata: message.metadata || {},
58
- action: route_info[:action],
59
- params: message.params.merge(route_info[:params])
60
- }
61
- end
62
-
63
50
  # Get and parse all request params
64
- def http_body_request_params
51
+ def request_params_all(request)
65
52
  request_params = HashWithIndifferentAccess.new
66
- request_params.merge!(@request.params || {})
53
+ request_params.merge!(request.params || {})
67
54
 
68
55
  # read post or put params. this will erase params
69
56
  # {code: 123, mode: 123}
70
57
  # "code=123&mode=123"
71
- request_body = @request.body.read
58
+ request_body = request.body.read
72
59
  if request_body.present?
73
60
  body_params = begin
74
61
  JSON.parse(request_body) # {code: 123, mode: 123}
@@ -23,39 +23,30 @@ module Webmate
23
23
  @packet_data = packet_data.with_indifferent_access
24
24
  end
25
25
 
26
- # packet should be created by socket.io spec
27
- # [message type] ':' [message id ('+')] ':' [message endpoint] (':' [message data])
28
- # and webmate spec
29
- # message_data = {
26
+ # Parse packet created by socket.io spec
27
+ # Packet format
28
+ # [packet type] ':' [packet id ('+')] ':' [packet endpoint] (':' [packet data])
29
+ #
30
+ # packet_data = {
30
31
  # method: GET/POST/...
31
32
  # path: '/projects'
32
- # params: {}
33
- # metadata: { data should be returned back with answer }
33
+ # params: {
34
+ # metadata: { data should be returned back with response },
35
+ # foor: 'bar'
36
+ # // and any other paranms
37
+ # }
38
+ # headers: [ {"SomeHeader": "SomeHeaderValue"} ]
34
39
  # }
35
40
  def self.parse(packet)
36
41
  # last element is encoded json array, so there can be many ':'
37
42
  packet_type_id, packet_id, packet_endpoint, json_data = packet.split(':', 4)
38
43
 
39
- packet_data = (Yajl::Parser.parse(json_data) || {}).with_indifferent_access
40
-
41
- if packet_data[:params].is_a?(String)
42
- packet_data[:params] = Yajl::Parser.parse(packet_data[:params])
43
- end
44
-
45
- if packet_data[:metadata].is_a?(String)
46
- packet_data[:metadata] = Yajl::Parser.parse(packet_data[:metadata])
47
- end
48
-
49
- packet = OpenStruct.new(
44
+ packet_data = (JSON.parse(json_data) rescue {}).with_indifferent_access
45
+ Webmate::SocketIO::Request.new(
50
46
  path: packet_data[:path],
51
- method: packet_data[:method],
52
- params: packet_data[:params] || {},
53
- metadata: packet_data[:metadata] || {},
54
- packet_id: packet_id,
55
- packet_endpoint: packet_endpoint
47
+ method: packet_data[:method].upcase,
48
+ params: packet_data[:params] || {}
56
49
  )
57
-
58
- packet
59
50
  end
60
51
 
61
52
  # convert response from Responders::Base to socket io message
@@ -69,7 +60,8 @@ module Webmate
69
60
  body: response.data,
70
61
  path: response.path,
71
62
  params: response.params,
72
- metadata: response.metadata
63
+ metadata: response.metadata,
64
+ status: response.status
73
65
  }
74
66
  end
75
67
 
@@ -0,0 +1,17 @@
1
+ # this class emulates Sinatra::Requst class for SocketIO.
2
+ module Webmate::SocketIO
3
+ class Request
4
+ attr_accessor :params, :path, :method, :body
5
+
6
+ def initialize(options = {})
7
+ @params = options[:params]
8
+ @path = options[:path]
9
+ @method = options[:method]
10
+ @body = options[:body] || ''
11
+ end
12
+
13
+ def body
14
+ @body.is_a?(String) ? StringIO.new(@body) : @body
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,3 @@
1
1
  module Webmate
2
- VERSION = '0.1.5'
2
+ VERSION = '0.1.6'
3
3
  end
@@ -15,14 +15,12 @@ module Webmate
15
15
 
16
16
  websocket.onmessage do |message|
17
17
  request = Webmate::SocketIO::Packets::Base.parse(message)
18
- response = block.call(request)
19
- if response
20
- packet = Webmate::SocketIO::Packets::Message.build_response_packet(response)
21
- websocket.send(packet.to_packet)
22
- else
23
- packet = Webmate::SocketIO::Packets::Error.build_response_packet("{error: 'empty response for #{message.inspect}'}")
24
- websocket.send(packet.to_packet)
18
+ response = begin
19
+ block.call(request) || Responders::Response.build_not_found("Action not found: #{request.path}")
20
+ rescue Exception => e
21
+ Responders::Response.build_error("Error while processing request: #{request.path}, #{e.message}")
25
22
  end
23
+ websocket.send(response.to_packet)
26
24
  end
27
25
 
28
26
  websocket.onclose do
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ def build_packet(data)
4
+ data = {
5
+ params: {
6
+ foo: 'bar',
7
+ metadata: {request_id: 'test'}
8
+ },
9
+ path: '/some/url',
10
+ method: 'GET'
11
+ }.merge(data)
12
+ "3:::#{Webmate::JSON.dump(data)}"
13
+ end
14
+
15
+ describe Webmate::SocketIO::Packets::Base do
16
+ let(:subject) { Webmate::SocketIO::Packets::Base }
17
+
18
+ describe "#parse" do
19
+ it "should parse packet data and return object compatible with Sinatra::Request" do
20
+ packet_data = build_packet(path: '/projects')
21
+ request = subject.parse(packet_data)
22
+ request.params[:metadata][:request_id].should == 'test'
23
+ request.method.should == 'GET'
24
+ end
25
+ end
26
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webmate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -232,6 +232,7 @@ files:
232
232
  - lib/webmate/socket.io/packets/json.rb
233
233
  - lib/webmate/socket.io/packets/message.rb
234
234
  - lib/webmate/socket.io/packets/noop.rb
235
+ - lib/webmate/socket.io/request.rb
235
236
  - lib/webmate/support/json.rb
236
237
  - lib/webmate/version.rb
237
238
  - lib/webmate/views/scope.rb
@@ -239,6 +240,7 @@ files:
239
240
  - spec/lib/application_spec.rb
240
241
  - spec/lib/routes/base_spec.rb
241
242
  - spec/lib/routes/collection_spec.rb
243
+ - spec/lib/socket.io/base_packet_spec.rb
242
244
  - spec/spec_helper.rb
243
245
  - webmate.gemspec
244
246
  homepage: https://github.com/webmate/webmate
@@ -256,7 +258,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
256
258
  version: '0'
257
259
  segments:
258
260
  - 0
259
- hash: 1691783446799875159
261
+ hash: -242899012726086530
260
262
  required_rubygems_version: !ruby/object:Gem::Requirement
261
263
  none: false
262
264
  requirements:
@@ -265,7 +267,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
265
267
  version: '0'
266
268
  segments:
267
269
  - 0
268
- hash: 1691783446799875159
270
+ hash: -242899012726086530
269
271
  requirements: []
270
272
  rubyforge_project:
271
273
  rubygems_version: 1.8.25