webmate 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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