carnivore-http 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7f9f4a7936dcc06d41a919c221612c146426790a
4
- data.tar.gz: 6153beb3e86f2dd7a3bf7eadad967a3fde8826b5
3
+ metadata.gz: 2f249ff2bcc32e656dea42855b1c9f5002c7f7c5
4
+ data.tar.gz: da5167bc1fa804b63b741da4bea7483d2d544653
5
5
  SHA512:
6
- metadata.gz: 459ee7c23877b7638eadf34b397dcfacec31237b7b6543ed0aaf7567ac26d155a87a422a1ea309bc7f09aaff0f82702321d51ab25a08e1e8c129f9042172697a
7
- data.tar.gz: 029e4ebfc459957bb46db5fc1f3590efa1126d3dedb0e4f2831b70cb480860d4a33d4675d5a87acdd798f00451d3276a0a953c8e181f7ffdbc03072fa3480f7a
6
+ metadata.gz: 5f6975483b01d2f7060cc6d213bd9513eb345b4c268fe0ddb0ab76b5a81026edb4bf421dcdb6fa07746ec647a3e9dd09f21a8846268e2dee8e90f0bdb4bacc1f
7
+ data.tar.gz: f1d1f7147463224541388146d95c9e19e7a4f8a5d86f045fa947e15c5f2db939e4655475bd476d8ab7ac05b24e0d8157cc2aedbc73ac5d8f29103132ca02843b
@@ -1,4 +1,8 @@
1
- # V0.2.0
1
+ # v0.2.2
2
+ * Add glob support to `:http_path` source
3
+ * Allow disabling automatic response on `:http_path`
4
+
5
+ # v0.2.0
2
6
  * Add support for message re-delivery and local persistence
3
7
  * Add support for authorization
4
8
  * Add HTTPS support
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- carnivore-http (0.1.9)
4
+ carnivore-http (0.2.1)
5
5
  blockenspiel
6
6
  carnivore (>= 0.1.8)
7
7
  htauth
@@ -12,15 +12,15 @@ GEM
12
12
  specs:
13
13
  attribute_struct (0.2.8)
14
14
  blockenspiel (0.4.5)
15
- bogo (0.1.6)
15
+ bogo (0.1.8)
16
16
  hashie
17
17
  multi_json
18
- bogo-config (0.1.6)
18
+ bogo-config (0.1.8)
19
19
  attribute_struct
20
20
  bogo (>= 0.1.4, < 1.0)
21
21
  multi_json
22
22
  multi_xml
23
- carnivore (0.3.4)
23
+ carnivore (0.3.6)
24
24
  bogo-config
25
25
  celluloid
26
26
  hashie
@@ -31,21 +31,18 @@ GEM
31
31
  celluloid (>= 0.16.0)
32
32
  nio4r (>= 1.1.0)
33
33
  form_data (0.1.0)
34
- hashie (3.3.2)
35
- highline (1.6.21)
34
+ hashie (3.4.0)
35
+ highline (1.7.0)
36
36
  hitimes (1.2.2)
37
- hitimes (1.2.2-java)
38
37
  htauth (1.1.0)
39
38
  highline (~> 1.6)
40
39
  http (0.7.1)
41
40
  form_data (~> 0.1.0)
42
41
  http_parser.rb (~> 0.6.0)
43
42
  http_parser.rb (0.6.0)
44
- http_parser.rb (0.6.0-java)
45
43
  multi_json (1.10.1)
46
44
  multi_xml (0.5.5)
47
45
  nio4r (1.1.0)
48
- nio4r (1.1.0-java)
49
46
  reel (0.5.0)
50
47
  celluloid (>= 0.15.1)
51
48
  celluloid-io (>= 0.15.0)
@@ -7,6 +7,11 @@ module Carnivore
7
7
  # Carnivore HTTP paths
8
8
  class HttpPaths < HttpSource
9
9
 
10
+ # Default max wait time for message response
11
+ DEFAULT_RESPONSE_TIMEOUT = 10
12
+ # Default response wait time stepping
13
+ DEFAULT_RESPONSE_WAIT_STEP = 0.1
14
+
10
15
  finalizer :halt_listener
11
16
  include Bogo::Memoization
12
17
 
@@ -32,9 +37,14 @@ module Carnivore
32
37
  if(message_queues[queue_key])
33
38
  raise ArgumentError.new "Conflicting HTTP path source provided! path: #{http_path} method: #{http_method}"
34
39
  else
35
- message_queues[queue_key] = Queue.new
40
+ message_queues[queue_key] = Smash.new(
41
+ :queue => Queue.new
42
+ )
36
43
  end
37
44
  super
45
+ message_queues[queue_key].merge!(
46
+ Smash.new(:config => args.to_smash)
47
+ )
38
48
  end
39
49
 
40
50
  # Setup the HTTP listener source
@@ -66,11 +76,35 @@ module Carnivore
66
76
  con.each_request do |req|
67
77
  begin
68
78
  msg = build_message(con, req)
69
- msg_queue = message_queues["#{req.path}-#{req.method.to_s.downcase}"]
79
+ # Start with static path lookup since it's the
80
+ # cheapest, then fallback to iterative globbing
81
+ msg_queue = nil
82
+ unless(msg_queue = message_queues["#{req.path}-#{req.method.to_s.downcase}"])
83
+ message_queues.each do |k,v|
84
+ path_glob, http_method = k.split('-')
85
+ if(req.method.to_s.downcase == http_method && File.fnmatch(path_glob, req.path))
86
+ msg_queue = v
87
+ end
88
+ end
89
+ end
70
90
  if(msg_queue)
71
91
  if(authorized?(msg))
72
- msg_queue << msg
73
- req.respond(:ok, 'So long and thanks for all the fish!')
92
+ msg_queue[:queue] << msg
93
+ if(msg_queue[:config][:auto_respond])
94
+ code = msg_queue[:config].fetch(:response, :code, 'ok').to_sym
95
+ response = msg_queue[:config].fetch(:response, :message, 'So long and thanks for all the fish!')
96
+ req.respond(code, response)
97
+ else
98
+ wait_time = msg_queue[:config].fetch(:response_timeout, DEFAULT_RESPONSE_TIMEOUT).to_f
99
+ wait_step = msg_queue[:config].fetch(:response_wait_step, DEFAULT_RESPONSE_WAIT_STEP).to_f
100
+ while(con.response_state == :headers && wait_time > 0)
101
+ sleep(wait_step)
102
+ wait_time -= wait_step
103
+ end
104
+ if(con.response_state == :headers)
105
+ raise "Timeout has been exceeded waiting for response! (#{msg})"
106
+ end
107
+ end
74
108
  else
75
109
  req.respond(:unauthorized, 'You are not authorized to perform requested action!')
76
110
  end
@@ -89,7 +123,7 @@ module Carnivore
89
123
  def receive(*_)
90
124
  val = nil
91
125
  until(val)
92
- val = Celluloid::Future.new{ message_queue.pop }.value
126
+ val = Celluloid::Future.new{ message_queue[:queue].pop }.value
93
127
  end
94
128
  val
95
129
  end
@@ -273,10 +273,14 @@ module Carnivore
273
273
  # @param args [Hash]
274
274
  # @option args [Symbol] :code return code
275
275
  def confirm(message, args={})
276
- code = args.delete(:code) || :ok
277
- args[:response_body] = 'Thanks' if code == :ok && args.empty?
278
- debug "Confirming #{message} with: Code: #{code.inspect} Args: #{args.inspect}"
279
- message[:message][:request].respond(code, args[:response_body] || args)
276
+ if(message[:message][:connection].response_state != :headers)
277
+ code = args.delete(:code) || :ok
278
+ args[:response_body] = 'Thanks' if code == :ok && args.empty?
279
+ debug "Confirming #{message} with: Code: #{code.inspect} Args: #{args.inspect}"
280
+ message[:message][:request].respond(code, args[:response_body] || args)
281
+ else
282
+ warn "Message was already confimed. Confirmation not sent! (#{message})"
283
+ end
280
284
  end
281
285
 
282
286
  # Initialize http listener correctly based on configuration
@@ -1,6 +1,6 @@
1
1
  module Carnivore
2
2
  module Http
3
3
  # current library version
4
- VERSION = Gem::Version.new('0.2.0')
4
+ VERSION = Gem::Version.new('0.2.2')
5
5
  end
6
6
  end
@@ -16,11 +16,12 @@ describe 'Carnivore::Source::Http' do
16
16
  :path => '/fubar',
17
17
  :method => :post,
18
18
  :bind => '127.0.0.1',
19
- :port => '8706'
19
+ :port => '8706',
20
+ :auto_respond => false
20
21
  }
21
22
  ).add_callback(:store) do |message|
22
23
  MessageStore.messages.push(message[:message][:body])
23
- message.confirm!
24
+ message.confirm!(:response_body => 'custom response')
24
25
  end
25
26
  Carnivore::Source.build(
26
27
  :type => :http_paths,
@@ -33,7 +34,18 @@ describe 'Carnivore::Source::Http' do
33
34
  }
34
35
  ).add_callback(:store) do |message|
35
36
  MessageStore.messages.push(message[:message][:body])
36
- message.confirm!
37
+ end
38
+ Carnivore::Source.build(
39
+ :type => :http_paths,
40
+ :args => {
41
+ :name => :glob_source,
42
+ :path => '/glob/v*/*',
43
+ :method => :get,
44
+ :bind => '127.0.0.1',
45
+ :port => '8706'
46
+ }
47
+ ).add_callback(:store) do |message|
48
+ MessageStore.messages.push(message[:message][:body])
37
49
  end
38
50
  @runner = Thread.new{ Carnivore.start! }
39
51
  source_wait
@@ -59,7 +71,7 @@ describe 'Carnivore::Source::Http' do
59
71
 
60
72
  end
61
73
 
62
- describe 'message transmissions' do
74
+ describe 'source message transmissions' do
63
75
 
64
76
  it 'should accept message transmits' do
65
77
  Carnivore::Supervisor.supervisor[:fubar_source].transmit('test message')
@@ -82,6 +94,31 @@ describe 'Carnivore::Source::Http' do
82
94
  end
83
95
 
84
96
  end
97
+
98
+ describe 'HTTP message transmissions' do
99
+
100
+ it 'should receive messages and provide custom response' do
101
+ response = HTTP.post('http://127.0.0.1:8706/fubar', :body => 'test')
102
+ response.body.to_s.must_equal 'custom response'
103
+ source_wait{ !MessageStore.messages.empty? }
104
+ MessageStore.messages.pop.must_equal 'test'
105
+ end
106
+
107
+ it 'should receive messages and provide default response' do
108
+ response = HTTP.get('http://127.0.0.1:8706/ohai')
109
+ source_wait{ !MessageStore.messages.empty? }
110
+ response.body.to_s.must_equal 'So long and thanks for all the fish!'
111
+ MessageStore.messages.pop.must_be :empty?
112
+ end
113
+
114
+ it 'should receive messages via glob matching' do
115
+ response = HTTP.get('http://127.0.0.1:8706/glob/v2/things')
116
+ source_wait{ !MessageStore.messages.empty? }
117
+ response.body.to_s.must_equal 'So long and thanks for all the fish!'
118
+ MessageStore.messages.pop.must_be :empty?
119
+ end
120
+
121
+ end
85
122
  end
86
123
 
87
124
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carnivore-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Roberts
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-01 00:00:00.000000000 Z
11
+ date: 2015-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: carnivore