hatetepe 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/hatetepe/app.rb CHANGED
@@ -17,7 +17,7 @@ module Hatetepe
17
17
  # Initializes a new App object.
18
18
  #
19
19
  # @param [#call] app
20
- # The Rack app
20
+ # The Rack app.
21
21
  #
22
22
  def initialize(app)
23
23
  @app = app
@@ -30,43 +30,48 @@ module Hatetepe
30
30
  # 500 response if the Rack app raises an error.
31
31
  #
32
32
  # @param [Hash] env
33
- # The Rack environment
33
+ # The Rack environment.
34
34
  #
35
35
  def call(env)
36
- env["async.callback"] = proc {|response|
36
+ env["async.callback"] = proc do |response|
37
37
  postprocess env, response
38
- }
38
+ end
39
39
 
40
40
  response = ASYNC_RESPONSE
41
- catch(:async) {
41
+ catch :async do
42
42
  response = app.call(env) rescue ERROR_RESPONSE
43
- }
43
+ end
44
+
44
45
  postprocess env, response
45
46
  end
46
47
 
47
48
  # Sends the response.
48
49
  #
49
50
  # Does nothing if response status is indicating an asynchronous response.
50
- # This is the case if the response Array's first element equals -1.
51
+ # This is the case if the response +Array+'s first element equals -1.
51
52
  # Otherwise it will start sending the response (status and headers).
52
53
  #
53
54
  # If the body indicates streaming it will return after sending the status
54
- # and headers. This happens if the body equals Rack::STREAMING. Otherwise
55
- # it sends each body chunk and then closes the response stream.
55
+ # and headers. This happens if the body equals +Rack::STREAMING+ or isn't
56
+ # set. Otherwise it sends each body chunk and then closes the response
57
+ # stream.
58
+ #
59
+ # Sending an empty body is as simple as passing an object that responds to
60
+ # +each+ but doesn't actually yield anything.
56
61
  #
57
62
  # @param [Hash] env
58
- # The Rack environment
63
+ # The Rack environment.
59
64
  # @param [Array] response
60
- # An array of 1..3 length containing the status, headers, body
65
+ # An array of 1..3 length containing the status, headers, body.
61
66
  #
62
67
  def postprocess(env, response)
63
68
  return if response[0] == ASYNC_RESPONSE[0]
64
69
 
65
70
  env["stream.start"].call response[0..1]
66
- return if response[2] == Rack::STREAMING
71
+ return if !response[2] || response[2] == Rack::STREAMING
67
72
 
68
73
  begin
69
- response[2].each {|chunk| env["stream.send"].call chunk }
74
+ response[2].each &env["stream.send"]
70
75
  ensure
71
76
  env["stream.close"].call
72
77
  end
data/lib/hatetepe/body.rb CHANGED
@@ -98,7 +98,7 @@ module Hatetepe
98
98
  # Immediately yields all data that has already arrived. Blocks until the
99
99
  # Body is write-closed and yields for each call to #write until then.
100
100
  #
101
- # @yield [String] Block to execute for each incoming data chunk
101
+ # @yield [String] Block to execute for each incoming data chunk.
102
102
  #
103
103
  # @return [undefined]
104
104
  def each(&block)
@@ -152,15 +152,15 @@ module Hatetepe
152
152
  # number of bytes written.
153
153
  #
154
154
  # @param [String] data
155
- # The data to append
155
+ # The data to append.
156
156
  #
157
157
  # @return [Fixnum]
158
158
  # The number of bytes written.
159
159
  def write(data)
160
160
  ret = io.write data
161
- Fiber.new {
161
+ Fiber.new do
162
162
  @receivers.each {|r| r.call data }
163
- }.resume
163
+ end.resume
164
164
  ret
165
165
  end
166
166
  end
@@ -158,9 +158,9 @@ module Hatetepe
158
158
  def error(message)
159
159
  exception = BuilderError.new(message)
160
160
  unless on_error.empty?
161
- on_error.each {|blk| blk.call(exception) }
161
+ on_error.each {|blk| blk.call exception }
162
162
  else
163
- raise(exception)
163
+ raise exception
164
164
  end
165
165
  end
166
166
  end
@@ -21,24 +21,25 @@ module Hatetepe
21
21
 
22
22
  headers["User-Agent"] ||= "hatetepe/#{VERSION}"
23
23
 
24
- EM::Synchrony.sync Request.new(verb, uri.request_uri).tap {|req|
24
+ Request.new(verb, uri.request_uri).tap do |req|
25
25
  req.headers = headers
26
26
  req.body = body || Body.new.tap {|b| b.close_write }
27
27
  client << req
28
- }
28
+ EM::Synchrony.sync req
29
+ end.response
29
30
  end
30
31
 
31
32
  class << self
32
- [:get, :head].each {|verb|
33
- define_method(verb) {|uri, headers = {}|
33
+ [:get, :head].each do |verb|
34
+ define_method verb do |uri, headers = {}|
34
35
  request verb.to_s.upcase, uri, headers
35
- }
36
- }
37
- [:options, :post, :put, :delete, :trace, :connect].each {|verb|
38
- define_method(verb) {|uri, headers = {}, body = nil|
36
+ end
37
+ end
38
+ [:options, :post, :put, :delete, :trace, :connect].each do |verb|
39
+ define_method verb do |uri, headers = {}, body = nil|
39
40
  request verb.to_s.upcase, uri, headers, body
40
- }
41
- }
41
+ end
42
+ end
42
43
  end
43
44
 
44
45
  attr_reader :config
@@ -52,17 +53,16 @@ module Hatetepe
52
53
  end
53
54
 
54
55
  def post_init
55
- parser.on_response {|response|
56
+ parser.on_response do |response|
56
57
  requests.find {|req| !req.response }.response = response
57
- }
58
+ end
58
59
 
59
- parser.on_headers {
60
- requests.reverse.find {|req| !!req.response }.tap {|req|
60
+ parser.on_headers do
61
+ requests.reverse.find {|req| !!req.response }.tap do |req|
62
+ req.response.body.source = self
61
63
  req.succeed req.response
62
- # XXX do i want to treat HEAD individually?
63
- parser.complete if req.verb == :head
64
- }
65
- }
64
+ end
65
+ end
66
66
 
67
67
  #builder.on_write {|chunk|
68
68
  # ap "-> #{chunk}"
@@ -74,7 +74,7 @@ module Hatetepe
74
74
  request.headers["Host"] = "#{config[:host]}:#{config[:port]}"
75
75
 
76
76
  requests << request
77
- Fiber.new {
77
+ Fiber.new do
78
78
  builder.request_line request.verb, request.uri
79
79
 
80
80
  if request.headers["Content-Type"] == "application/x-www-form-urlencoded"
@@ -96,7 +96,7 @@ module Hatetepe
96
96
  end
97
97
 
98
98
  builder.complete
99
- }.resume
99
+ end.resume
100
100
  end
101
101
 
102
102
  def receive_data(data)
@@ -105,11 +105,7 @@ module Hatetepe
105
105
  end
106
106
 
107
107
  def stop
108
- close_connection_after_writing
109
- end
110
-
111
- def responses
112
- requests.map(&:response).compact
108
+ close_connection
113
109
  end
114
110
  end
115
111
  end
@@ -12,23 +12,23 @@ module Hatetepe
12
12
 
13
13
  def event!(name, *args)
14
14
  @state = name
15
- event(name, *args)
15
+ event name, *args
16
16
  end
17
17
 
18
18
  module ClassMethods
19
19
  def event(name, *more_names)
20
- define_method(:"on_#{name}") {|&block|
20
+ define_method :"on_#{name}" do |&block|
21
21
  ivar = :"@on_#{name}"
22
22
  store = instance_variable_get(ivar)
23
23
  store ||= instance_variable_set(ivar, [])
24
24
 
25
25
  return store unless block
26
26
  store << block
27
- }
27
+ end
28
28
 
29
29
  define_method(:"#{name}?") { state == name }
30
30
 
31
- more_names.each {|n| event n }
31
+ more_names.each &method(:event)
32
32
  end
33
33
  end
34
34
  end
@@ -19,8 +19,8 @@ module Hatetepe
19
19
  attr_reader :message
20
20
 
21
21
  def initialize(&block)
22
- @parser = HTTP::Parser.new.tap {|p|
23
- p.on_headers_complete = proc {
22
+ @parser = HTTP::Parser.new.tap do |p|
23
+ p.on_headers_complete = proc do
24
24
  version = p.http_version.join(".")
25
25
  if p.http_method
26
26
  @message = Request.new(p.http_method, p.request_url, version)
@@ -35,14 +35,14 @@ module Hatetepe
35
35
 
36
36
  event! :body, message.body
37
37
  nil
38
- }
38
+ end
39
39
 
40
- p.on_body = proc {|chunk|
40
+ p.on_body = proc do |chunk|
41
41
  message.body.write chunk unless message.body.closed_write?
42
- }
42
+ end
43
43
 
44
44
  p.on_message_complete = method(:complete)
45
- }
45
+ end
46
46
 
47
47
  reset
48
48
 
@@ -0,0 +1,27 @@
1
+ module Hatetepe
2
+ # TODO move specs from server_spec.rb to pipeline_spec.rb
3
+ class Pipeline
4
+ attr_reader :app
5
+
6
+ def initialize(app)
7
+ @app = app
8
+ end
9
+
10
+ def call(env)
11
+ previous, request = env["hatetepe.connection"].requests.values_at(-2, -1)
12
+ blocks = env.values_at("stream.start", "stream.close")
13
+
14
+ env["stream.start"] = proc do |response|
15
+ EM::Synchrony.sync previous if previous
16
+ blocks[0].call response
17
+ end
18
+
19
+ env["stream.close"] = proc do
20
+ blocks[1].call
21
+ request.succeed
22
+ end
23
+
24
+ app.call env
25
+ end
26
+ end
27
+ end
@@ -27,12 +27,12 @@ module Hatetepe
27
27
  build_request(env, target).tap do |req|
28
28
  cl << req
29
29
  EM::Synchrony.sync req
30
- cl.stop unless client
30
+ req.response.body.callback { cl.stop } unless client
31
31
  env["proxy.callback"].call req.response
32
32
  end
33
33
  end
34
34
 
35
- # TODO only use +env+ to build the request
35
+ # TODO use only +env+ to build the request
36
36
  def build_request(env, target)
37
37
  unless base = env["hatetepe.request"]
38
38
  raise ArgumentError, "Proxying requires env[hatetepe.request] to be set"
@@ -18,16 +18,16 @@ module Hatetepe
18
18
  "rack.input" => body,
19
19
  "REQUEST_METHOD" => verb.dup,
20
20
  "REQUEST_URI" => uri.dup
21
- }.tap {|hsh|
22
- headers.each {|key, value|
21
+ }.tap do |hsh|
22
+ headers.each do |key, value|
23
23
  key = key.upcase.gsub! /[^A-Z]/, "_"
24
24
  key = "HTTP_#{key}" unless key =~ /^CONTENT_(TYPE|LENGTH)$/
25
- hsh[key] = value
26
- }
25
+ hsh[key] = value.dup
26
+ end
27
27
 
28
28
  hsh["REQUEST_PATH"], qm, hsh["QUERY_STRING"] = uri.partition("?")
29
29
  hsh["PATH_INFO"], hsh["SCRIPT_NAME"] = hsh["REQUEST_PATH"].dup, ""
30
- }
30
+ end
31
31
  end
32
32
  end
33
33
  end
@@ -13,8 +13,8 @@ module Hatetepe
13
13
  [status, headers, body]
14
14
  end
15
15
 
16
- def [](i)
17
- to_a[i]
16
+ def [](idx)
17
+ to_a[idx]
18
18
  end
19
19
  end
20
20
  end
@@ -5,14 +5,15 @@ require "rack"
5
5
  require "hatetepe/app"
6
6
  require "hatetepe/builder"
7
7
  require "hatetepe/parser"
8
+ require "hatetepe/pipeline"
9
+ require "hatetepe/proxy"
8
10
  require "hatetepe/request"
9
11
  require "hatetepe/version"
10
12
 
11
13
  module Hatetepe
12
14
  class Server < EM::Connection
13
15
  def self.start(config)
14
- server = EM.start_server(config[:host], config[:port], self, config)
15
- #Prefork.run server if config[:prefork]
16
+ EM.start_server config[:host], config[:port], self, config
16
17
  end
17
18
 
18
19
  attr_reader :app, :config, :errors
@@ -21,12 +22,13 @@ module Hatetepe
21
22
  def initialize(config)
22
23
  @config = config
23
24
  @errors = config[:errors] || $stderr
24
-
25
- @app = Rack::Builder.new.tap {|b|
25
+
26
+ @app = Rack::Builder.new.tap do |b|
27
+ b.use Hatetepe::Pipeline
26
28
  b.use Hatetepe::App
27
29
  b.use Hatetepe::Proxy
28
30
  b.run config[:app]
29
- }
31
+ end.to_app
30
32
 
31
33
  super
32
34
  end
@@ -53,49 +55,53 @@ module Hatetepe
53
55
  end
54
56
 
55
57
  def process(*)
56
- previous, request = requests.values_at(-2, -1)
58
+ request = requests.last
57
59
 
58
- env = request.to_hash.tap {|e|
59
- e["hatetepe.connection"] = self
60
- e["rack.url_scheme"] = "http"
61
- e["rack.input"].source = self
62
- e["rack.errors"] = errors
63
-
64
- e["rack.multithread"] = false
65
- e["rack.multiprocess"] = false
66
- e["rack.run_once"] = false
67
-
68
- e["SERVER_NAME"] = config[:host].dup
69
- e["SERVER_PORT"] = String(config[:port])
70
-
71
- host = e["HTTP_HOST"] || config[:host].dup
72
- host += ":#{config[:port]}" unless host.include? ":"
73
- e["HTTP_HOST"] = host
74
-
75
- e["stream.start"] = proc {|response|
60
+ env = request.to_hash.tap do |e|
61
+ inject_environment e
62
+ e["stream.start"] = proc do |response|
76
63
  e.delete "stream.start"
77
- EM::Synchrony.sync previous if previous
78
-
79
- builder.response_line response[0]
80
- response[1]["Server"] = "hatetepe/#{VERSION}"
81
- builder.headers response[1]
82
- }
83
-
64
+ start_response response
65
+ end
84
66
  e["stream.send"] = builder.method(:body_chunk)
85
-
86
- e["stream.close"] = proc {
67
+ e["stream.close"] = proc do
87
68
  e.delete "stream.send"
88
69
  e.delete "stream.close"
89
-
90
- builder.complete
91
- requests.delete request
92
- request.succeed
93
-
94
- close_connection_after_writing if requests.empty?
95
- }
96
- }
70
+ close_response request
71
+ end
72
+ end
97
73
 
98
74
  Fiber.new { app.call env }.resume
99
75
  end
76
+
77
+ def start_response(response)
78
+ builder.response_line response[0]
79
+ response[1]["Server"] = "hatetepe/#{VERSION}"
80
+ builder.headers response[1]
81
+ end
82
+
83
+ def close_response(request)
84
+ builder.complete
85
+ requests.delete request
86
+ close_connection_after_writing if requests.empty?
87
+ end
88
+
89
+ def inject_environment(env)
90
+ env["hatetepe.connection"] = self
91
+ env["rack.url_scheme"] = "http"
92
+ env["rack.input"].source = self
93
+ env["rack.errors"] = errors
94
+
95
+ env["rack.multithread"] = false
96
+ env["rack.multiprocess"] = false
97
+ env["rack.run_once"] = false
98
+
99
+ env["SERVER_NAME"] = config[:host].dup
100
+ env["SERVER_PORT"] = String(config[:port])
101
+
102
+ host = env["HTTP_HOST"] || config[:host].dup
103
+ host += ":#{config[:port]}" unless host.include? ":"
104
+ env["HTTP_HOST"] = host
105
+ end
100
106
  end
101
107
  end
@@ -1,3 +1,3 @@
1
1
  module Hatetepe
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
data/lib/hatetepe.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  require "hatetepe/builder"
2
2
  require "hatetepe/client"
3
3
  require "hatetepe/parser"
4
- require "hatetepe/proxy"
5
4
  require "hatetepe/request"
6
5
  require "hatetepe/response"
7
6
  require "hatetepe/server"
@@ -15,10 +15,10 @@ module Rack
15
15
  Signal.trap("TERM") { EM.stop }
16
16
 
17
17
  EM.epoll
18
- EM.synchrony {
18
+ EM.synchrony do
19
19
  server = ::Hatetepe::Server.start options
20
20
  yield server if block_given?
21
- }
21
+ end
22
22
  end
23
23
 
24
24
  def self.valid_options
@@ -6,9 +6,9 @@ describe Hatetepe::App do
6
6
  let(:app) { Hatetepe::App.new inner_app }
7
7
  let(:env) {
8
8
  {
9
- "stream.start" => stub("stream.start", :call => nil),
10
- "stream.send" => stub("stream.send", :call => nil),
11
- "stream.close" => stub("stream.close", :call => nil)
9
+ "stream.start" => proc {},
10
+ "stream.send" => proc {},
11
+ "stream.close" => proc {}
12
12
  }
13
13
  }
14
14
 
@@ -81,16 +81,22 @@ describe Hatetepe::App do
81
81
  end
82
82
 
83
83
  it "streams the body" do
84
- env["stream.send"].should_receive(:call).with(body[0])
85
- env["stream.send"].should_receive(:call).with(body[1])
84
+ body.should_receive :each do |&blk|
85
+ blk.should equal(env["stream.send"])
86
+ end
86
87
  app.postprocess env, [status, headers, body]
87
88
  end
88
89
 
89
90
  it "doesn't stream the body if it equals Rack::STREAMING" do
90
- env["stream.send"].should_not_receive :call
91
+ body.should_not_receive :each
91
92
  app.postprocess env, [status, headers, Rack::STREAMING]
92
93
  end
93
94
 
95
+ it "doesn't try to stream a body that isn't set" do
96
+ body.should_not_receive :each
97
+ app.postprocess env, [status, headers]
98
+ end
99
+
94
100
  it "closes the response stream after streaming the body" do
95
101
  env["stream.close"].should_receive :call
96
102
  app.postprocess env, [status, headers, body]
@@ -162,7 +162,7 @@ describe Hatetepe::Client do
162
162
  }
163
163
  }
164
164
  }
165
- let(:response) { stub "response" }
165
+ let(:response) { stub "response", :body => Hatetepe::Body.new }
166
166
 
167
167
  before {
168
168
  client.post_init
@@ -246,25 +246,8 @@ describe Hatetepe::Client do
246
246
 
247
247
  context "#stop" do
248
248
  it "closes the connection" do
249
- client.should_receive :close_connection_after_writing
249
+ client.should_receive :close_connection
250
250
  client.stop
251
251
  end
252
252
  end
253
-
254
- context "#responses" do
255
- let(:requests) {
256
- 4.times.map {|i| stub "request##{i}", :response => responses[i] }
257
- }
258
- let(:responses) {
259
- 2.times.map {|i| stub "response##{i}" }
260
- }
261
-
262
- before {
263
- client.stub :requests => requests
264
- }
265
-
266
- it "returns all requests' responses" do
267
- client.responses.should == responses
268
- end
269
- end
270
253
  end
@@ -40,16 +40,18 @@ describe Hatetepe::Server do
40
40
 
41
41
  context "#initialize(config)" do
42
42
  let(:server) { Hatetepe::Server.allocate }
43
- let(:builder) { stub "app builder" }
43
+ let(:builder) { stub "app builder", :to_app => to_app }
44
+ let(:to_app) { stub "to_app" }
44
45
 
45
46
  it "builds the app" do
46
47
  Rack::Builder.stub :new => builder
48
+ builder.should_receive(:use).with Hatetepe::Pipeline
47
49
  builder.should_receive(:use).with Hatetepe::App
48
50
  builder.should_receive(:use).with Hatetepe::Proxy
49
51
  builder.should_receive(:run).with app
50
52
 
51
53
  server.send :initialize, config
52
- server.app.should equal(builder)
54
+ server.app.should equal(to_app)
53
55
  end
54
56
 
55
57
  it "sets up the error stream" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hatetepe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-01 00:00:00.000000000Z
12
+ date: 2011-11-05 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: http_parser.rb
16
- requirement: &85707400 !ruby/object:Gem::Requirement
16
+ requirement: &83959440 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.5.3
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *85707400
24
+ version_requirements: *83959440
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: eventmachine
27
- requirement: &85706930 !ruby/object:Gem::Requirement
27
+ requirement: &83959120 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *85706930
35
+ version_requirements: *83959120
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: em-synchrony
38
- requirement: &85706430 !ruby/object:Gem::Requirement
38
+ requirement: &83958600 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '1.0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *85706430
46
+ version_requirements: *83958600
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rack
49
- requirement: &85705840 !ruby/object:Gem::Requirement
49
+ requirement: &83958210 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *85705840
57
+ version_requirements: *83958210
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: async-rack
60
- requirement: &85705450 !ruby/object:Gem::Requirement
60
+ requirement: &83957590 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *85705450
68
+ version_requirements: *83957590
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: thor
71
- requirement: &85705070 !ruby/object:Gem::Requirement
71
+ requirement: &83957070 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *85705070
79
+ version_requirements: *83957070
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rspec
82
- requirement: &85704360 !ruby/object:Gem::Requirement
82
+ requirement: &83956480 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *85704360
90
+ version_requirements: *83956480
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: fakefs
93
- requirement: &85703690 !ruby/object:Gem::Requirement
93
+ requirement: &83956060 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *85703690
101
+ version_requirements: *83956060
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: em-http-request
104
- requirement: &85703190 !ruby/object:Gem::Requirement
104
+ requirement: &83955480 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ~>
@@ -109,7 +109,7 @@ dependencies:
109
109
  version: '1.0'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *85703190
112
+ version_requirements: *83955480
113
113
  description:
114
114
  email:
115
115
  - lars.gierth@gmail.com
@@ -136,6 +136,7 @@ files:
136
136
  - lib/hatetepe/events.rb
137
137
  - lib/hatetepe/message.rb
138
138
  - lib/hatetepe/parser.rb
139
+ - lib/hatetepe/pipeline.rb
139
140
  - lib/hatetepe/proxy.rb
140
141
  - lib/hatetepe/request.rb
141
142
  - lib/hatetepe/response.rb