carnivore-http 0.1.0 → 0.1.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/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: []