htttee 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.gitignore +1 -2
  2. data/.travis.yml +6 -0
  3. data/README.md +13 -1
  4. data/bin/htttee +2 -2
  5. data/bin/htttee-exec +8 -7
  6. data/config.ru +1 -1
  7. data/htttee.gemspec +4 -3
  8. data/lib/htttee/client.rb +4 -6
  9. data/lib/htttee/client/consumer.rb +38 -34
  10. data/lib/htttee/server.rb +45 -39
  11. data/lib/htttee/server/api.rb +155 -139
  12. data/lib/htttee/server/chunked_body.rb +13 -15
  13. data/lib/htttee/server/middleware/async_fixer.rb +12 -15
  14. data/lib/htttee/server/middleware/dechunker.rb +44 -45
  15. data/lib/htttee/server/middleware/rechunker.rb +15 -0
  16. data/lib/htttee/server/mock.rb +44 -46
  17. data/lib/htttee/server/pubsub_redis.rb +4 -0
  18. data/lib/htttee/server/sse/body.rb +71 -0
  19. data/lib/htttee/server/sse/middleware.rb +96 -0
  20. data/lib/htttee/version.rb +2 -4
  21. data/spec/client_spec.rb +102 -2
  22. data/spec/helpers/rackup.rb +1 -1
  23. data/spec/spec_helper.rb +3 -3
  24. metadata +72 -46
  25. data/deploy/after_restart.rb +0 -1
  26. data/deploy/before_restart.rb +0 -4
  27. data/deploy/before_symlink.rb +0 -2
  28. data/deploy/cookbooks/cloudkick-plugins/recipes/default.rb +0 -8
  29. data/deploy/cookbooks/cloudkick-plugins/recipes/resque.rb +0 -18
  30. data/deploy/cookbooks/cloudkick-plugins/templates/default/resque.sh.erb +0 -4
  31. data/deploy/cookbooks/god/recipes/default.rb +0 -50
  32. data/deploy/cookbooks/god/templates/default/config.erb +0 -3
  33. data/deploy/cookbooks/god/templates/default/god-inittab.erb +0 -3
  34. data/deploy/cookbooks/main/attributes/owner_name.rb +0 -3
  35. data/deploy/cookbooks/main/attributes/recipes.rb +0 -1
  36. data/deploy/cookbooks/main/libraries/dnapi.rb +0 -7
  37. data/deploy/cookbooks/main/recipes/default.rb +0 -2
  38. data/deploy/cookbooks/nginx/files/default/chunkin-nginx-module-v0.22rc1.zip +0 -0
  39. data/deploy/cookbooks/nginx/files/default/nginx-1.0.0.tar.gz +0 -0
  40. data/deploy/cookbooks/nginx/recipes/default.rb +0 -2
  41. data/deploy/cookbooks/nginx/recipes/install.rb +0 -0
  42. data/deploy/cookbooks/nginx/templates/default/nginx.conf.erb +0 -41
  43. data/deploy/cookbooks/resque/recipes/default.rb +0 -47
  44. data/deploy/cookbooks/resque/templates/default/resque.rb.erb +0 -73
  45. data/deploy/cookbooks/resque/templates/default/resque.yml.erb +0 -3
  46. data/deploy/cookbooks/resque/templates/default/resque_scheduler.rb.erb +0 -73
  47. data/deploy/solo.rb +0 -7
@@ -1,5 +1,3 @@
1
- module EY
2
- module Tea
3
- VERSION = '0.0.0'
4
- end
1
+ module HTTTee
2
+ VERSION = '0.6.0'
5
3
  end
@@ -1,13 +1,17 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe EY::Tea::Client do
3
+ describe HTTTee::Client do
4
4
  subject { @client }
5
5
 
6
6
  def new_client
7
- EY::Tea::Client.new(:endpoint => EY::Tea::Server.mock_uri.to_s)
7
+ HTTTee::Client.new(:endpoint => HTTTee::Server.mock_uri.to_s)
8
8
  end
9
9
 
10
10
  def run(thread)
11
+ if RUBY_VERSION =~ /^2\./
12
+ return Thread.pass if thread == Thread.main
13
+ end
14
+
11
15
  thread.join(0.1) if thread.alive?
12
16
  end
13
17
 
@@ -37,10 +41,12 @@ describe EY::Tea::Client do
37
41
  client.up(reader, uuid)
38
42
  end
39
43
 
44
+ client_called = false
40
45
  down_thread = Thread.new(new_client, i, scheduler) do |client, writer|
41
46
  run scheduler
42
47
  client.down(uuid) do |chunk|
43
48
  if chunk == 'Hello, '
49
+ client_called = true
44
50
  writer << 'World!'
45
51
  writer.close
46
52
  run scheduler
@@ -48,10 +54,48 @@ describe EY::Tea::Client do
48
54
  end
49
55
  end
50
56
 
57
+ client_called.should be_false
58
+
51
59
  run up_thread
52
60
  run down_thread
53
61
  run up_thread
54
62
  run down_thread
63
+
64
+ client_called.should be_true
65
+ end
66
+
67
+ it "can accept a stream containing CRLFs." do
68
+ scheduler = Thread.current
69
+ uuid = rand(10_000).to_s
70
+ o, i = IO.pipe
71
+ i << "Hello, \r\n\r\nthere"
72
+
73
+ up_thread = Thread.new(new_client, o) do |client, reader|
74
+ run scheduler
75
+ client.up(reader, uuid)
76
+ end
77
+
78
+ client_called = false
79
+
80
+ down_thread = Thread.new(new_client, i, scheduler) do |client, writer|
81
+ run scheduler
82
+ client.down(uuid) do |chunk|
83
+ if chunk == "Hello, \r\n\r\nthere"
84
+ client_called = true
85
+ writer.close
86
+ run scheduler
87
+ end
88
+ end
89
+ end
90
+
91
+ client_called.should be_false
92
+
93
+ run up_thread
94
+ run down_thread
95
+ run up_thread
96
+ run down_thread
97
+
98
+ client_called.should be_true
55
99
  end
56
100
 
57
101
  it "streams already recieved data on an open stream to peers." do
@@ -123,4 +167,60 @@ describe EY::Tea::Client do
123
167
  i.close
124
168
  end
125
169
 
170
+ it "gets the SSE setup page if the client supports SSE." do
171
+ scheduler = Thread.current
172
+ uuid = rand(10_000).to_s
173
+ o, i = IO.pipe
174
+ i << 'Ignore Me!'
175
+ i.close
176
+
177
+ up_thread = Thread.new(new_client, o) do |client, reader|
178
+ client.up(reader, uuid)
179
+ end
180
+
181
+ run up_thread
182
+
183
+ client = Rack::Client.new(HTTTee::Server.mock_uri.to_s)
184
+
185
+ response = client.get(uuid, 'User-Agent' => 'OctoWebKit', 'Accept' => 'text/html')
186
+
187
+ response.headers['Content-Type'].should == 'text/html'
188
+ response.body =~ /new EventSource/
189
+ end
190
+
191
+ it "gets the SSE stream response when making an SSE request." do
192
+ scheduler = Thread.current
193
+ uuid = rand(10_000).to_s
194
+ o, i = IO.pipe
195
+ i << "Don't Ignore Me!\nPlease!"
196
+ i.close
197
+
198
+ up_thread = Thread.new(new_client, o) do |client, reader|
199
+ client.up(reader, uuid)
200
+ end
201
+
202
+ run up_thread
203
+
204
+ client = Rack::Client.new(HTTTee::Server.mock_uri.to_s)
205
+
206
+ response = client.get(uuid, 'User-Agent' => 'OctoWebKit', 'Accept' => 'text/event-stream')
207
+
208
+ response.headers['Content-Type'].should == 'text/event-stream'
209
+
210
+ response.body.should == <<-BODY
211
+ event: message
212
+ data: Don't Ignore Me!
213
+
214
+ event: ctrl
215
+ data: newline
216
+
217
+ event: message
218
+ data: Please!
219
+
220
+ event: ctrl
221
+ data: eof
222
+
223
+ BODY
224
+ end
225
+
126
226
  end
@@ -1,4 +1,4 @@
1
- module TeaHelpers
1
+ module HTTTeeHelpers
2
2
  class ThinMuxer
3
3
  def initialize(app)
4
4
  @app = Rack::Mux.new(thin_options)
@@ -6,16 +6,16 @@ require 'htttee/client'
6
6
 
7
7
  require 'digest/sha2'
8
8
 
9
- EY::Tea::Server.mock!
9
+ HTTTee::Server.mock!
10
10
  Thin::Logging.debug = Thin::Logging.trace = true
11
11
 
12
12
  RSpec.configure do |config|
13
13
  config.color_enabled = config.tty = true #Force ANSI colors
14
14
 
15
15
  config.around :each do |callback|
16
- EY::Tea::Server.reset!
16
+ HTTTee::Server.reset!
17
17
 
18
- @client = EY::Tea::Client.new(:endpoint => EY::Tea::Server.mock_uri.to_s)
18
+ @client = HTTTee::Client.new(:endpoint => HTTTee::Server.mock_uri.to_s)
19
19
  callback.run
20
20
  end
21
21
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: htttee
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,27 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-12 00:00:00.000000000 Z
12
+ date: 2013-07-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack-client
16
- requirement: &70348419674800 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ~>
19
+ - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 0.3.1.pre.i
21
+ version: 0.4.2
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70348419674800
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 0.4.2
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: trollop
27
- requirement: &70348419673880 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,10 +37,15 @@ dependencies:
32
37
  version: '0'
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *70348419673880
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: sinatra
38
- requirement: &70348420159880 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ! '>='
@@ -43,10 +53,15 @@ dependencies:
43
53
  version: '0'
44
54
  type: :development
45
55
  prerelease: false
46
- version_requirements: *70348420159880
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: thin
49
- requirement: &70348420156740 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ! '>='
@@ -54,10 +69,15 @@ dependencies:
54
69
  version: '0'
55
70
  type: :development
56
71
  prerelease: false
57
- version_requirements: *70348420156740
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
58
78
  - !ruby/object:Gem::Dependency
59
79
  name: em-redis
60
- requirement: &70348420155620 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
61
81
  none: false
62
82
  requirements:
63
83
  - - ! '>='
@@ -65,10 +85,15 @@ dependencies:
65
85
  version: '0'
66
86
  type: :development
67
87
  prerelease: false
68
- version_requirements: *70348420155620
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
69
94
  - !ruby/object:Gem::Dependency
70
95
  name: yajl-ruby
71
- requirement: &70348420154460 !ruby/object:Gem::Requirement
96
+ requirement: !ruby/object:Gem::Requirement
72
97
  none: false
73
98
  requirements:
74
99
  - - ! '>='
@@ -76,10 +101,15 @@ dependencies:
76
101
  version: '0'
77
102
  type: :development
78
103
  prerelease: false
79
- version_requirements: *70348420154460
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
80
110
  - !ruby/object:Gem::Dependency
81
111
  name: rack-mux
82
- requirement: &70348420168760 !ruby/object:Gem::Requirement
112
+ requirement: !ruby/object:Gem::Requirement
83
113
  none: false
84
114
  requirements:
85
115
  - - ! '>='
@@ -87,10 +117,15 @@ dependencies:
87
117
  version: '0'
88
118
  type: :development
89
119
  prerelease: false
90
- version_requirements: *70348420168760
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
91
126
  - !ruby/object:Gem::Dependency
92
127
  name: rspec
93
- requirement: &70348420167380 !ruby/object:Gem::Requirement
128
+ requirement: !ruby/object:Gem::Requirement
94
129
  none: false
95
130
  requirements:
96
131
  - - ! '>='
@@ -98,10 +133,15 @@ dependencies:
98
133
  version: '0'
99
134
  type: :development
100
135
  prerelease: false
101
- version_requirements: *70348420167380
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
102
142
  - !ruby/object:Gem::Dependency
103
143
  name: rake
104
- requirement: &70348420165540 !ruby/object:Gem::Requirement
144
+ requirement: !ruby/object:Gem::Requirement
105
145
  none: false
106
146
  requirements:
107
147
  - - ! '>='
@@ -109,7 +149,12 @@ dependencies:
109
149
  version: '0'
110
150
  type: :development
111
151
  prerelease: false
112
- version_requirements: *70348420165540
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
113
158
  description: Stream any CLI output as an HTTP chunked response.
114
159
  email:
115
160
  - ben@benburkert.com
@@ -120,35 +165,13 @@ extensions: []
120
165
  extra_rdoc_files: []
121
166
  files:
122
167
  - .gitignore
168
+ - .travis.yml
123
169
  - Gemfile
124
170
  - README.md
125
171
  - Rakefile
126
172
  - bin/htttee
127
173
  - bin/htttee-exec
128
174
  - config.ru
129
- - deploy/after_restart.rb
130
- - deploy/before_restart.rb
131
- - deploy/before_symlink.rb
132
- - deploy/cookbooks/cloudkick-plugins/recipes/default.rb
133
- - deploy/cookbooks/cloudkick-plugins/recipes/resque.rb
134
- - deploy/cookbooks/cloudkick-plugins/templates/default/resque.sh.erb
135
- - deploy/cookbooks/god/recipes/default.rb
136
- - deploy/cookbooks/god/templates/default/config.erb
137
- - deploy/cookbooks/god/templates/default/god-inittab.erb
138
- - deploy/cookbooks/main/attributes/owner_name.rb
139
- - deploy/cookbooks/main/attributes/recipes.rb
140
- - deploy/cookbooks/main/libraries/dnapi.rb
141
- - deploy/cookbooks/main/recipes/default.rb
142
- - deploy/cookbooks/nginx/files/default/chunkin-nginx-module-v0.22rc1.zip
143
- - deploy/cookbooks/nginx/files/default/nginx-1.0.0.tar.gz
144
- - deploy/cookbooks/nginx/recipes/default.rb
145
- - deploy/cookbooks/nginx/recipes/install.rb
146
- - deploy/cookbooks/nginx/templates/default/nginx.conf.erb
147
- - deploy/cookbooks/resque/recipes/default.rb
148
- - deploy/cookbooks/resque/templates/default/resque.rb.erb
149
- - deploy/cookbooks/resque/templates/default/resque.yml.erb
150
- - deploy/cookbooks/resque/templates/default/resque_scheduler.rb.erb
151
- - deploy/solo.rb
152
175
  - htttee.gemspec
153
176
  - lib/htttee.rb
154
177
  - lib/htttee/client.rb
@@ -165,8 +188,11 @@ files:
165
188
  - lib/htttee/server/ext/thin/deferred_response.rb
166
189
  - lib/htttee/server/middleware/async_fixer.rb
167
190
  - lib/htttee/server/middleware/dechunker.rb
191
+ - lib/htttee/server/middleware/rechunker.rb
168
192
  - lib/htttee/server/mock.rb
169
193
  - lib/htttee/server/pubsub_redis.rb
194
+ - lib/htttee/server/sse/body.rb
195
+ - lib/htttee/server/sse/middleware.rb
170
196
  - lib/htttee/version.rb
171
197
  - spec/client_spec.rb
172
198
  - spec/helpers/rackup.rb
@@ -191,7 +217,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
191
217
  version: '0'
192
218
  requirements: []
193
219
  rubyforge_project: htttee
194
- rubygems_version: 1.8.10
220
+ rubygems_version: 1.8.23
195
221
  signing_key:
196
222
  specification_version: 3
197
223
  summary: Unix's tee as a service
@@ -1 +0,0 @@
1
- sudo "god signal resque-#{app} QUIT"
@@ -1,4 +0,0 @@
1
- on_app_servers do
2
- env_custom = "#{shared_path}/config/env.custom"
3
- run "echo 'export APP_CURRENT_PATH=\"#{current_path}\"' > #{env_custom}"
4
- end
@@ -1,2 +0,0 @@
1
- sudo "/usr/local/ey_resin/ruby/bin/chef-solo " \
2
- "-c #{latest_release}/deploy/solo.rb -j /etc/chef/dna.json"
@@ -1,8 +0,0 @@
1
- directory "/usr/lib/cloudkick-agent/plugins" do
2
- owner "root"
3
- group "root"
4
- action :create
5
- recursive true
6
- end
7
-
8
- require_recipe "cloudkick-plugins::resque"
@@ -1,18 +0,0 @@
1
- execute 'restart-cloudkick-agent' do
2
- action :nothing
3
-
4
- command 'pkill cloudkick-agent'
5
- end
6
-
7
- template "/usr/lib/cloudkick-agent/plugins/resque" do
8
- mode "0755"
9
- source "resque.sh.erb"
10
- variables(
11
- :dir => "/data/#{node.engineyard.environment.apps.first.name}/current",
12
- :script => "script/cloudkick-resque",
13
- :rack_env => node.engineyard.environment.framework_env,
14
- :redis_uri => "#{node.engineyard.environment.db_host}:6379"
15
- )
16
-
17
- notifies :run, resources(:execute => 'restart-cloudkick-agent')
18
- end