carnivore-http 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,2 +1,7 @@
1
+ # v0.1.2
2
+ * Include query parameters
3
+ * Start basic test coverage
4
+ * Update message confirmation behavior
5
+
1
6
  # v0.1.0
2
7
  * Initial release
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,50 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ carnivore-http (0.1.1)
5
+ blockenspiel
6
+ carnivore (>= 0.1.8)
7
+ reel
8
+
9
+ PATH
10
+ remote: ../carnivore
11
+ specs:
12
+ carnivore (0.1.11)
13
+ celluloid
14
+ mixlib-config
15
+ multi_json
16
+
17
+ GEM
18
+ remote: https://rubygems.org/
19
+ specs:
20
+ blockenspiel (0.4.5)
21
+ celluloid (0.15.2)
22
+ timers (~> 1.1.0)
23
+ celluloid-io (0.15.0)
24
+ celluloid (>= 0.15.0)
25
+ nio4r (>= 0.5.0)
26
+ http (0.5.0)
27
+ http_parser.rb
28
+ http_parser.rb (0.6.0.beta.2)
29
+ http_parser.rb (0.6.0.beta.2-java)
30
+ mixlib-config (2.0.0)
31
+ multi_json (1.8.2)
32
+ nio4r (0.5.0)
33
+ nio4r (0.5.0-java)
34
+ reel (0.4.0)
35
+ celluloid (>= 0.15.1)
36
+ celluloid-io (>= 0.15.0)
37
+ http (>= 0.5.0)
38
+ http_parser.rb (>= 0.6.0.beta.2)
39
+ websocket_parser (>= 0.1.4)
40
+ timers (1.1.0)
41
+ websocket_parser (0.1.4)
42
+ http
43
+
44
+ PLATFORMS
45
+ java
46
+ ruby
47
+
48
+ DEPENDENCIES
49
+ carnivore!
50
+ carnivore-http!
data/README.md CHANGED
@@ -31,6 +31,6 @@ end.start!
31
31
  ```
32
32
 
33
33
  # Info
34
- * Carnivore: https://github.com/heavywater/carnivore
35
- * Repository: https://github.com/heavywater/carnivore-http
36
- * IRC: Freenode @ #heavywater
34
+ * Carnivore: https://github.com/carnivore-rb/carnivore
35
+ * Repository: https://github.com/carnivore-rb/carnivore-http
36
+ * IRC: Freenode @ #carnivore
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
6
6
  s.summary = 'Message processing helper'
7
7
  s.author = 'Chris Roberts'
8
8
  s.email = 'chrisroberts.code@gmail.com'
9
- s.homepage = 'https://github.com/heavywater/carnivore-http'
9
+ s.homepage = 'https://github.com/carnivore-rb/carnivore-http'
10
10
  s.description = 'Carnivore HTTP source'
11
11
  s.require_path = 'lib'
12
12
  s.add_dependency 'carnivore', '>= 0.1.8'
@@ -1,11 +1,14 @@
1
1
  require 'reel'
2
2
  require 'carnivore/source'
3
+ require 'carnivore-http/utils'
3
4
 
4
5
  module Carnivore
5
6
  class Source
6
7
 
7
8
  class Http < Source
8
9
 
10
+ include Carnivore::Http::Utils::Params
11
+
9
12
  attr_reader :args
10
13
 
11
14
  def setup(args={})
@@ -20,24 +23,59 @@ module Carnivore
20
23
  }.merge(args)
21
24
  end
22
25
 
23
- def transmit(message, orignal_message_or_connection, args={})
24
- if(original_message_or_connection.is_a?(Message))
25
- con = original_message_or_connection[:connection]
26
+ # Transmit can be one of two things:
27
+ # 1. Response back to an open connection
28
+ # 2. Request to a remote source
29
+ def transmit(message, *extra)
30
+ options = extra.detect{|x| x.is_a?(Hash)} || {}
31
+ orig = extra.detect{|x| x.is_a?(Carnivore::Message)}
32
+ con = options[:connection]
33
+ if(orig && con.nil?)
34
+ con = orig[:message][:connection]
35
+ end
36
+ if(con) # response
37
+ payload = message.is_a?(String) ? message : MultiJson.dump(message)
38
+ # TODO: add `options` options for marshaling: json/xml/etc
39
+ debug "Transmit response type with payload: #{payload}"
40
+ con.respond(options[:code] || :ok, payload)
41
+ else # request
42
+ url = File.join("http://#{args[:bind]}:#{args[:port]}", options[:path].to_s)
43
+ method = (options[:method] || :post).to_sym
44
+ if(options[:headers])
45
+ base = HTTP.with_headers(options[:headers])
46
+ else
47
+ base = HTTP
48
+ end
49
+ payload = message.is_a?(String) ? message : MultiJson.dump(message)
50
+ debug "Transmit request type with payload: #{payload}"
51
+ base.send(method, url, :body => payload)
52
+ end
53
+ end
54
+
55
+ def confirm(message, args={})
56
+ if(args[:response_body] || args[:code])
57
+ debug "Confirming #{message} with: #{args.inspect}"
58
+ message[:message][:connection].respond(
59
+ args[:code] || :ok, args[:response_body] || 'Thanks!'
60
+ )
26
61
  else
27
- con = original_message_or_connection[:connection]
62
+ debug "Confirming #{message}. No arguments provided so no response taken."
28
63
  end
29
- # TODO: add `args` options for marshaling: json/xml/etc
30
- con.respond(args[:code] || :ok, message)
31
64
  end
32
65
 
33
66
  def process(*process_args)
34
67
  srv = Reel::Server.supervise(args[:bind], args[:port]) do |con|
35
68
  while(req = con.request)
36
69
  begin
37
- msg = format(:request => req, :body => req.body, :connection => con)
70
+ msg = format(
71
+ :request => req,
72
+ :body => req.body.to_s,
73
+ :connection => con,
74
+ :query => parse_query_string(req.query_string)
75
+ )
38
76
  callbacks.each do |name|
39
77
  c_name = callback_name(name)
40
- debug "Dispatching message<#{msg[:message].object_id}> to callback<#{name} (#{c_name})>"
78
+ debug "Dispatching #{msg} to callback<#{name} (#{c_name})>"
41
79
  Celluloid::Actor[c_name].async.call(msg)
42
80
  end
43
81
  con.respond(:ok, 'So long, and thanks for all the fish!') if args[:auto_respond]
@@ -60,7 +60,12 @@ module Carnivore
60
60
  srv = Reel::Server.supervise(args[:bind], args[:port]) do |con|
61
61
  con.each_request do |req|
62
62
  begin
63
- msg = format(:request => req, :body => req.body, :connection => con)
63
+ msg = format(
64
+ :request => req,
65
+ :body => req.body.to_s,
66
+ :connection => con,
67
+ :query => parse_query_string(req.query_string)
68
+ )
64
69
  unless(@points.deliver(msg))
65
70
  con.respond(:ok, 'So long, and thanks for all the fish!')
66
71
  end
@@ -9,6 +9,7 @@ module Carnivore
9
9
  class Endpoint
10
10
 
11
11
  include Celluloid
12
+ include Carnivore::Utils::Params
12
13
  include Carnivore::Utils::Logging
13
14
 
14
15
  attr_reader :endpoint, :type
@@ -16,7 +17,7 @@ module Carnivore
16
17
  def initialize(type, endpoint, block)
17
18
  @endpoint = endpoint
18
19
  @type = type
19
- define_singleton_method(:run, &block)
20
+ define_singleton_method(:execute, &block)
20
21
  end
21
22
 
22
23
  def to_s
@@ -66,10 +67,10 @@ module Carnivore
66
67
  end
67
68
  if(match)
68
69
  if(static[type][match][:async])
69
- Celluloid::Actor[callback_name(match, type)].async.run(msg)
70
- false
70
+ Celluloid::Actor[callback_name(match, type)].async.execute(msg)
71
+ true
71
72
  else
72
- Celluloid::Actor[callback_name(match, type)].run(msg)
73
+ Celluloid::Actor[callback_name(match, type)].execute(msg)
73
74
  true
74
75
  end
75
76
  end
@@ -83,12 +84,12 @@ module Carnivore
83
84
  [point, res.first.is_a?(Array) ? res.first : []]
84
85
  end
85
86
  end.compact.first
86
- unless(match.empty?)
87
+ if(match && !match.empty?)
87
88
  if(regex[type][match.first][:async])
88
- Celluloid::Actor[callback_name(match.first, type)].async.run([msg] + match.last)
89
- false
89
+ Celluloid::Actor[callback_name(match.first, type)].async.execute(*([msg] + match.last))
90
+ true
90
91
  else
91
- Celluloid::Actor[callback_name(match.first, type)].run([msg] + match.last)
92
+ Celluloid::Actor[callback_name(match.first, type)].execute(*([msg] + match.last))
92
93
  true
93
94
  end
94
95
  end
@@ -0,0 +1,66 @@
1
+ module Carnivore
2
+ module Http
3
+ module Utils
4
+ module Params
5
+
6
+ class << self
7
+
8
+ def included(klass)
9
+ require 'cgi'
10
+ end
11
+
12
+ end
13
+
14
+ # string:: HTTP query string
15
+ # Return Hash of parsed query string
16
+ def parse_query_string(string)
17
+ unless(string.to_s.empty?)
18
+ args = CGI.parse(string)
19
+ format_query_args(args)
20
+ else
21
+ {}
22
+ end
23
+ end
24
+
25
+ # args:: HTTP query string Hash
26
+ # Return formatted hash with inferred types
27
+ def format_query_args(args)
28
+ new_args = {}
29
+ args.each do |k, v|
30
+ k = k.to_sym
31
+ case v
32
+ when Hash
33
+ new_args[k] = format_query_args(v)
34
+ when Array
35
+ v = v.map{|obj| format_query_type(obj)}
36
+ new_args[k] = v.size == 1 ? v.first : v
37
+ else
38
+ new_args[k] = format_query_type(v)
39
+ end
40
+ end
41
+ new_args
42
+ end
43
+
44
+ # obj:: object
45
+ # Attempts to return true type
46
+ def format_query_type(obj)
47
+ case obj
48
+ when 'true'
49
+ true
50
+ when 'false'
51
+ false
52
+ else
53
+ if(obj.to_i.to_s == obj)
54
+ obj.to_i
55
+ elsif(obj.to_f.to_s == obj)
56
+ obj.to_f
57
+ else
58
+ obj
59
+ end
60
+ end
61
+ end
62
+
63
+ end
64
+ end
65
+ end
66
+ end
@@ -2,6 +2,6 @@ module Carnivore
2
2
  module Http
3
3
  class Version < Gem::Version
4
4
  end
5
- VERSION = Version.new('0.1.0')
5
+ VERSION = Version.new('0.1.2')
6
6
  end
7
7
  end
data/test/spec.rb ADDED
@@ -0,0 +1 @@
1
+ require 'carnivore/spec_helper'
@@ -0,0 +1,66 @@
1
+ require 'http'
2
+ require 'minitest/autorun'
3
+ require 'carnivore-http'
4
+
5
+ describe 'Carnivore::Source::Http' do
6
+
7
+ describe 'Building an HTTP based source' do
8
+
9
+ it 'returns the source' do
10
+ Carnivore::Source.build(
11
+ :type => :http,
12
+ :args => {
13
+ :name => :http_source,
14
+ :bind => '127.0.0.1',
15
+ :port => '8705'
16
+ }
17
+ )
18
+ t = Thread.new{ Carnivore.start! }
19
+ source_wait
20
+ Celluloid::Actor[:http_source].wont_be_nil
21
+ t.terminate
22
+ end
23
+
24
+ end
25
+
26
+ describe 'HTTP source based communication' do
27
+ before do
28
+ MessageStore.init
29
+ Carnivore::Source.build(
30
+ :type => :http,
31
+ :args => {
32
+ :name => :http_source,
33
+ :bind => '127.0.0.1',
34
+ :port => '8705'
35
+ }
36
+ ).add_callback(:store) do |message|
37
+ MessageStore.messages.push(message[:message][:body])
38
+ end
39
+ @runner = Thread.new{ Carnivore.start! }
40
+ source_wait
41
+ end
42
+
43
+ after do
44
+ @runner.terminate
45
+ end
46
+
47
+ describe 'message transmissions' do
48
+ it 'should accept message transmits' do
49
+ Celluloid::Actor[:http_source].transmit('test message')
50
+ end
51
+
52
+ it 'should receive messages' do
53
+ Celluloid::Actor[:http_source].transmit('test message 2')
54
+ source_wait
55
+ MessageStore.messages.pop.must_equal 'test message 2'
56
+ end
57
+
58
+ it 'should accept http requests' do
59
+ HTTP.get('http://127.0.0.1:8705/')
60
+ source_wait
61
+ MessageStore.messages.pop.wont_be_nil
62
+ end
63
+ end
64
+ end
65
+
66
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carnivore-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-15 00:00:00.000000000 Z
12
+ date: 2013-12-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: carnivore
@@ -68,12 +68,17 @@ files:
68
68
  - lib/carnivore-http/point_builder.rb
69
69
  - lib/carnivore-http/version.rb
70
70
  - lib/carnivore-http/http.rb
71
+ - lib/carnivore-http/utils.rb
71
72
  - lib/carnivore-http/http_endpoints.rb
72
73
  - lib/carnivore-http.rb
74
+ - test/spec.rb
75
+ - test/specs/http.rb
76
+ - Gemfile
73
77
  - README.md
74
78
  - carnivore-http.gemspec
75
79
  - CHANGELOG.md
76
- homepage: https://github.com/heavywater/carnivore-http
80
+ - Gemfile.lock
81
+ homepage: https://github.com/carnivore-rb/carnivore-http
77
82
  licenses: []
78
83
  post_install_message:
79
84
  rdoc_options: []