request-replay 0.6.3 → 0.7.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 16053b14d0f25a8a0a55a8416692f3a40438e06c
4
- data.tar.gz: 8fb2ba84a1f33fbed931f0542cc692dfa96e932c
3
+ metadata.gz: 0335c8c8c412eae553868c108b0d157521c76b0b
4
+ data.tar.gz: 393e2da293913de62fff4960b5e6fb12b70f6593
5
5
  SHA512:
6
- metadata.gz: 1608f535929798711724cc4c8a5b0ef2aea2294085226d472f9bf27295a06de5385817e0a0cd349bee0fb1bd4a49b0ed98fb2d963d77bb639c35e7fbf47ca4e5
7
- data.tar.gz: 9a5826abe20eccc9b24827e2df6065fad4b573cec50c4a08186626fb2a55faf4bc63e91b9140a090413606831abb7b7ec2b8b62a2a2a72560469ffb5e8b92238
6
+ metadata.gz: 854270e4079d0737727d53e88f9ceabb836f16ecbbb6cbd7fde7a4400625ea999451c6931d7d1e406216f14cf83bb75cea257110d25657b861c0d4c3e5a03ada
7
+ data.tar.gz: dc452c780b57c25e28d763acccc48f3e0efa8d71472a772174bdac7ebd525e7af65f303b6d82e230037ef452cdb31585dd9148b7f7c088ec69869c84f4526cce
@@ -1,11 +1,9 @@
1
1
  before_install: 'git submodule update --init'
2
2
  script: 'ruby -r bundler/setup -S rake test'
3
3
 
4
- env:
5
- - 'RBXOPT=-X19'
6
-
7
4
  rvm:
8
5
  - 1.9.3
9
6
  - 2.0.0
10
- - rbx-head
11
- - jruby-head
7
+ - ruby
8
+ - rbx
9
+ - jruby
data/CHANGES.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # CHANGES
2
2
 
3
+ ## request-replay 0.7.0 -- 2014-03-30
4
+
5
+ * Fixed a bug where nginx with sendfile on might not send a full file back.
6
+ * Introduced RequestReplay::Proxy which could serve as a reverse proxy.
7
+
3
8
  ## request-replay 0.6.3 -- 2013-10-07
4
9
 
5
10
  * Fixed an issue where Rack::Request does not try to rewind rack.input for
data/Gemfile CHANGED
@@ -1,5 +1,11 @@
1
1
 
2
2
  source 'https://rubygems.org'
3
+
3
4
  gemspec
4
5
 
5
6
  gem 'rake'
7
+ gem 'bacon'
8
+
9
+ platform :rbx do
10
+ gem 'rubysl-singleton' # used in rake
11
+ end
data/README.md CHANGED
@@ -43,6 +43,24 @@ use RequestReplay::Middleware, 'localhost:8080',
43
43
  run lambda{ |env| [200, {}, [env.inspect]] }
44
44
  ```
45
45
 
46
+ You could also use `RequestReplay::Proxy` as a reverse proxy. Note that
47
+ this only works on Rack servers which support [Rack Hijacking][].
48
+
49
+ [Rack Hijacking]: http://rack.rubyforge.org/doc/SPEC.html
50
+
51
+ ``` ruby
52
+ require 'request-replay'
53
+ run RequestReplay::Proxy.new(
54
+ 'example.com', :add_headers => {'Host' => 'example.com'},
55
+ # We could also rewrite the env
56
+ :rewrite_env => lambda{ |env|
57
+ if env['HTTP_HOST'].start_with?('api.')
58
+ env['PATH_INFO'] = "/api/#{env['PATH_INFO']}"
59
+ end
60
+ env
61
+ })
62
+ ```
63
+
46
64
  ## CONTRIBUTORS:
47
65
 
48
66
  * Jim Wang (@yyjim)
@@ -52,7 +70,7 @@ run lambda{ |env| [200, {}, [env.inspect]] }
52
70
 
53
71
  Apache License 2.0
54
72
 
55
- Copyright (c) 2013, Lin Jen-Shin (godfat)
73
+ Copyright (c) 2013-2014, Lin Jen-Shin (godfat)
56
74
 
57
75
  Licensed under the Apache License, Version 2.0 (the "License");
58
76
  you may not use this file except in compliance with the License.
data/Rakefile CHANGED
@@ -8,6 +8,6 @@ end
8
8
 
9
9
  Gemgem.init(dir) do |s|
10
10
  s.name = 'request-replay'
11
- s.version = '0.6.3'
11
+ s.version = '0.7.0'
12
12
  %w[bacon muack rack].each{ |g| s.add_development_dependency(g) }
13
13
  end
@@ -4,6 +4,7 @@ require 'stringio'
4
4
 
5
5
  class RequestReplay
6
6
  autoload :Middleware, 'request-replay/middleware'
7
+ autoload :Proxy , 'request-replay/proxy'
7
8
 
8
9
  NEWLINE = "\r\n" .freeze
9
10
  HTTP_VERSION = 'HTTP/1.1' .freeze
@@ -25,6 +26,8 @@ class RequestReplay
25
26
  IO.copy_stream(env[RACK_INPUT], @buf)
26
27
  @buf.rewind
27
28
  env[RACK_INPUT].rewind
29
+ else
30
+ @buf = nil
28
31
  end
29
32
  end
30
33
 
@@ -40,7 +43,6 @@ class RequestReplay
40
43
  write_request
41
44
  write_headers
42
45
  write_payload
43
- sock.close_write
44
46
  IO.select([sock], [], [], read_wait) if read_wait
45
47
  yield(sock) if block_given?
46
48
  rescue => e
@@ -7,17 +7,19 @@ class RequestReplay::Middleware
7
7
  end
8
8
 
9
9
  def call env
10
- # Unfortunately, we need to dup env because other middleware might be
11
- # modifying it and make RequestReplay not able to get the original env.
12
- rr_env = if rewrite = @options[:rewrite_env]
13
- rewrite.call(env.dup)
14
- else
15
- env.dup
16
- end
17
-
18
10
  # We don't want to read the socket in a thread, so create it in main
19
11
  # thread, and send the data in a thread as we don't care the responses.
20
- Thread.new(RequestReplay.new(rr_env, @host, @options), &:start)
12
+ Thread.new(RequestReplay.new(rewrite_env(env), @host, @options), &:start)
21
13
  @app.call(env)
22
14
  end
15
+
16
+ def rewrite_env env
17
+ # Unfortunately, we need to dup env because other middleware might be
18
+ # modifying it and make RequestReplay not able to get the original env.
19
+ if rewrite = @options[:rewrite_env]
20
+ rewrite.call(env.dup)
21
+ else
22
+ env.dup
23
+ end
24
+ end
23
25
  end
@@ -0,0 +1,25 @@
1
+
2
+ require 'request-replay'
3
+
4
+ class RequestReplay::Proxy
5
+ def initialize host, options={}
6
+ @host, @options = host, options
7
+ end
8
+
9
+ def call env
10
+ env['rack.hijack'].call
11
+ RequestReplay.new(rewrite_env(env), @host, @options).start do |sock|
12
+ IO.copy_stream(sock, env['rack.hijack_io'])
13
+ env['rack.hijack_io'].close
14
+ end
15
+ [200, {}, []]
16
+ end
17
+
18
+ def rewrite_env env
19
+ if rewrite = @options[:rewrite_env]
20
+ rewrite.call(env)
21
+ else
22
+ env
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,38 @@
1
+
2
+ require 'bacon'
3
+ require 'muack'
4
+
5
+ require 'request-replay'
6
+ require 'rack'
7
+
8
+ Bacon.summary_on_exit
9
+ Bacon::Context.__send__(:include, Muack::API)
10
+
11
+ module Kernel
12
+ def eq? rhs
13
+ self == rhs
14
+ end
15
+ end
16
+
17
+ shared :test do
18
+ @host = 'localhost'.freeze
19
+ @port = 1024 + rand(2**16 - 1024)
20
+ @serv = TCPServer.new('localhost', @port)
21
+ @hopt = "#{@host}:#{@port}".freeze
22
+ @env = {'REQUEST_METHOD' => 'GET',
23
+ 'PATH_INFO' => '/', 'QUERY_STRING' => 'q=1',
24
+ 'HTTP_HOST' => 'localhost',
25
+ 'HTTP_PORK' => 'BEEF' }.freeze
26
+
27
+ @verify = lambda do |response, expected|
28
+ sock = @serv.accept
29
+ if expected.start_with?('POST')
30
+ sock.readline("\r\n\r\n") + sock.readline("\r\n\r\n")
31
+ else
32
+ sock.readline("\r\n\r\n")
33
+ end.should.eq(expected)
34
+ sock.write(expected)
35
+ sock.close
36
+ response.value.should.eq(expected)
37
+ end
38
+ end
@@ -1,13 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: request-replay 0.6.3 ruby lib
2
+ # stub: request-replay 0.7.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "request-replay"
6
- s.version = "0.6.3"
6
+ s.version = "0.7.0"
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
+ s.require_paths = ["lib"]
9
10
  s.authors = ["Lin Jen-Shin (godfat)"]
10
- s.date = "2013-10-07"
11
+ s.date = "2014-03-30"
11
12
  s.description = "Replay the request via Rack env"
12
13
  s.email = ["godfat (XD) godfat.org"]
13
14
  s.files = [
@@ -21,16 +22,22 @@ Gem::Specification.new do |s|
21
22
  "Rakefile",
22
23
  "lib/request-replay.rb",
23
24
  "lib/request-replay/middleware.rb",
25
+ "lib/request-replay/proxy.rb",
26
+ "lib/request-replay/test.rb",
24
27
  "request-replay.gemspec",
25
- "task/.gitignore",
28
+ "task/README.md",
26
29
  "task/gemgem.rb",
27
- "test/test_basic.rb"]
30
+ "test/test_middleware.rb",
31
+ "test/test_proxy.rb",
32
+ "test/test_request-replay.rb"]
28
33
  s.homepage = "https://github.com/godfat/request-replay"
29
34
  s.licenses = ["Apache License 2.0"]
30
- s.require_paths = ["lib"]
31
- s.rubygems_version = "2.1.5"
35
+ s.rubygems_version = "2.2.2"
32
36
  s.summary = "Replay the request via Rack env"
33
- s.test_files = ["test/test_basic.rb"]
37
+ s.test_files = [
38
+ "test/test_middleware.rb",
39
+ "test/test_proxy.rb",
40
+ "test/test_request-replay.rb"]
34
41
 
35
42
  if s.respond_to? :specification_version then
36
43
  s.specification_version = 4
@@ -0,0 +1,54 @@
1
+ # Gemgem
2
+
3
+ ## DESCRIPTION:
4
+
5
+ Provided tasks:
6
+
7
+ rake clean # Remove ignored files
8
+ rake gem:build # Build gem
9
+ rake gem:install # Install gem
10
+ rake gem:release # Release gem
11
+ rake gem:spec # Generate gemspec
12
+ rake test # Run tests in memory
13
+
14
+ ## REQUIREMENTS:
15
+
16
+ * Tested with MRI (official CRuby) 1.9.3, 2.0.0, Rubinius and JRuby.
17
+
18
+ ## INSTALLATION:
19
+
20
+ git submodule add git://github.com/godfat/gemgem.git task
21
+
22
+ And in Rakefile:
23
+
24
+ ``` ruby
25
+ begin
26
+ require "#{dir = File.dirname(__FILE__)}/task/gemgem"
27
+ rescue LoadError
28
+ sh 'git submodule update --init'
29
+ exec Gem.ruby, '-S', $PROGRAM_NAME, *ARGV
30
+ end
31
+
32
+ Gemgem.init(dir) do |s|
33
+ s.name = 'your-gem'
34
+ s.version = '0.1.0'
35
+ end
36
+ ```
37
+
38
+ ## LICENSE:
39
+
40
+ Apache License 2.0
41
+
42
+ Copyright (c) 2011-2013, Lin Jen-Shin (godfat)
43
+
44
+ Licensed under the Apache License, Version 2.0 (the "License");
45
+ you may not use this file except in compliance with the License.
46
+ You may obtain a copy of the License at
47
+
48
+ <http://www.apache.org/licenses/LICENSE-2.0>
49
+
50
+ Unless required by applicable law or agreed to in writing, software
51
+ distributed under the License is distributed on an "AS IS" BASIS,
52
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
53
+ See the License for the specific language governing permissions and
54
+ limitations under the License.
@@ -144,20 +144,18 @@ module Gemgem
144
144
  end
145
145
 
146
146
  def ignored_pattern
147
- @ignored_pattern ||= Regexp.new(expand_patterns(gitignore).join('|'))
147
+ @ignored_pattern ||= if gitignore.empty?
148
+ /^$/
149
+ else
150
+ Regexp.new(expand_patterns(gitignore).join('|'))
151
+ end
148
152
  end
149
153
 
150
154
  def expand_patterns pathes
151
155
  # http://git-scm.com/docs/gitignore
152
156
  pathes.flat_map{ |path|
153
- case path
154
- when %r{\*}
155
- Regexp.escape(path).gsub(/\\\*/, '[^/]*')
156
- when %r{^/}
157
- "^#{Regexp.escape(path[1..-1])}"
158
- else # we didn't implement negative pattern for now
159
- Regexp.escape(path)
160
- end
157
+ # we didn't implement negative pattern for now
158
+ Regexp.escape(path).sub(%r{^/}, '^').gsub(/\\\*/, '[^/]*')
161
159
  }
162
160
  end
163
161
 
@@ -226,7 +224,7 @@ end
226
224
 
227
225
  end # of gem namespace
228
226
 
229
- desc 'Run tests in memory'
227
+ desc 'Run tests'
230
228
  task :test do
231
229
  next if Gemgem.test_files.empty?
232
230
 
@@ -236,7 +234,7 @@ task :test do
236
234
  Gemgem.test_files.each{ |file| require "#{Gemgem.dir}/#{file[0..-4]}" }
237
235
  end
238
236
 
239
- desc 'Remove ignored files'
237
+ desc 'Trash ignored files'
240
238
  task :clean => ['gem:spec'] do
241
239
  next if Gemgem.ignored_files.empty?
242
240
 
@@ -0,0 +1,79 @@
1
+
2
+ require 'request-replay/test'
3
+
4
+ describe RequestReplay::Middleware do
5
+ behaves_like :test
6
+
7
+ should 'PUT' do
8
+ hopt = @hopt
9
+ app = Rack::Builder.app do
10
+ use RequestReplay::Middleware, hopt
11
+ run lambda{ |_| [200, {}, []] }
12
+ end
13
+
14
+ app.call(@env.merge('REQUEST_METHOD' => 'PUT'))
15
+ begin
16
+ sock = @serv.accept
17
+ sock.read.should.eq <<-HTTP
18
+ PUT /?q=1 HTTP/1.1\r
19
+ Host: localhost\r
20
+ Pork: BEEF\r
21
+ \r
22
+ HTTP
23
+ ensure
24
+ sock.close
25
+ end
26
+ end
27
+
28
+ should 'retain original env' do
29
+ hopt = @hopt
30
+ e = @env.dup
31
+
32
+ app = Rack::Builder.app do
33
+ use RequestReplay::Middleware, hopt
34
+ run lambda{ |env|
35
+ env['PATH_INFO'] = '/bad'
36
+ [200, {}, []]
37
+ }
38
+ end
39
+
40
+ app.call(e)
41
+ begin
42
+ sock = @serv.accept
43
+ sock.read.should.eq <<-HTTP
44
+ GET /?q=1 HTTP/1.1\r
45
+ Host: localhost\r
46
+ Pork: BEEF\r
47
+ \r
48
+ HTTP
49
+ ensure
50
+ sock.close
51
+ end
52
+ end
53
+
54
+ should 'rewrite_env' do
55
+ hopt = @hopt
56
+ app = Rack::Builder.app do
57
+ use RequestReplay::Middleware, hopt, :rewrite_env => lambda{ |env|
58
+ if env['HTTP_HOST'].start_with?('api.')
59
+ env['PATH_INFO'] = "/api#{env['PATH_INFO']}"
60
+ end
61
+ env
62
+ }, :add_headers => {'Host' => 'eg.com'}
63
+ run lambda{ |_| [200, {}, []] }
64
+ end
65
+
66
+ app.call(@env.merge('HTTP_HOST' => 'api.localhost'))
67
+ begin
68
+ sock = @serv.accept
69
+ sock.read.should.eq <<-HTTP
70
+ GET /api/?q=1 HTTP/1.1\r
71
+ Host: eg.com\r
72
+ Pork: BEEF\r
73
+ \r
74
+ HTTP
75
+ ensure
76
+ sock.close
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,68 @@
1
+
2
+
3
+ require 'request-replay/test'
4
+
5
+ describe RequestReplay::Proxy do
6
+ behaves_like :test
7
+
8
+ request = lambda do |env, buf, options={}|
9
+ mock(buf).close
10
+ Thread.new{
11
+ begin
12
+ RequestReplay::Proxy.new(@hopt, options).call(env)
13
+ buf.string
14
+ rescue => e
15
+ p e
16
+ end
17
+ }
18
+ end
19
+
20
+ after do
21
+ Muack.verify
22
+ end
23
+
24
+ should 'basic' do
25
+ expected = <<-HTTP
26
+ GET /?q=1 HTTP/1.1\r
27
+ Host: localhost\r
28
+ Pork: BEEF\r
29
+ \r
30
+ HTTP
31
+
32
+ buf = StringIO.new
33
+ env = {'rack.hijack' => mock.call{ env['rack.hijack_io'] = buf }.object}.
34
+ merge(@env)
35
+
36
+ @verify[request[env, buf], expected]
37
+ end
38
+
39
+ should 'add_headers' do
40
+ expected = <<-HTTP
41
+ GET /?q=1 HTTP/1.1\r
42
+ Host: ex.com\r
43
+ Pork: BEEF\r
44
+ \r
45
+ HTTP
46
+
47
+ buf = StringIO.new
48
+ env = {'rack.hijack' => mock.call{ env['rack.hijack_io'] = buf }.object}.
49
+ merge(@env)
50
+
51
+ @verify[request[env, buf, :add_headers => {'Host' => 'ex.com'}], expected]
52
+ end
53
+
54
+ should 'rewrite_env' do
55
+ expected = <<-HTTP
56
+ GET /a?q=1 HTTP/1.1\r
57
+ Host: localhost\r
58
+ Pork: BEEF\r
59
+ \r
60
+ HTTP
61
+
62
+ buf = StringIO.new
63
+ env = {'rack.hijack' => mock.call{ env['rack.hijack_io'] = buf }.object}.
64
+ merge(@env)
65
+ rewrite_env = lambda{ |env| env['PATH_INFO'] = '/a'; env }
66
+ @verify[request[env, buf, :rewrite_env => rewrite_env], expected]
67
+ end
68
+ end
@@ -0,0 +1,78 @@
1
+
2
+ require 'request-replay/test'
3
+
4
+ describe RequestReplay do
5
+ behaves_like :test
6
+
7
+ request = lambda do |env, headers={}, read_wait=nil|
8
+ Thread.new(RequestReplay.new(@env.merge(env), @hopt,
9
+ :add_headers => headers,
10
+ :read_wait => read_wait)) do |replay|
11
+ replay.start(&:read)
12
+ end
13
+ end
14
+
15
+ after do
16
+ Muack.verify
17
+ end
18
+
19
+ should 'GET' do
20
+ @verify[request[{'REQUEST_METHOD' => 'GET'}, 'Host' => 'ex.com'], <<-HTTP]
21
+ GET /?q=1 HTTP/1.1\r
22
+ Host: ex.com\r
23
+ Pork: BEEF\r
24
+ \r
25
+ HTTP
26
+ end
27
+
28
+ should 'POST' do
29
+ @verify[request['REQUEST_METHOD' => 'POST',
30
+ 'QUERY_STRING' => '' , # test no query string
31
+ 'PATH_INFO' => '' , # test no path info
32
+ 'rack.input' => StringIO.new("PAYLOAD\r\n\r\n")], <<-HTTP]
33
+ POST / HTTP/1.1\r
34
+ Host: localhost\r
35
+ Pork: BEEF\r
36
+ \r
37
+ PAYLOAD\r
38
+ \r
39
+ HTTP
40
+ end
41
+
42
+ should 'read_wait' do
43
+ read_wait = 5
44
+ mock(IO).select(satisfy{ |rs| rs.size == 1 &&
45
+ rs[0].kind_of?(IO) },
46
+ [], [], read_wait)
47
+
48
+ @verify[request[{}, {}, read_wait], <<-HTTP]
49
+ GET /?q=1 HTTP/1.1\r
50
+ Host: localhost\r
51
+ Pork: BEEF\r
52
+ \r
53
+ HTTP
54
+ end
55
+
56
+ should 'puts error' do
57
+ any_instance_of(TCPSocket) do |sock|
58
+ mock(sock).read{ raise 'ERROR' }
59
+ end
60
+
61
+ errors = StringIO.new
62
+ begin
63
+ request['rack.errors' => errors].value
64
+ ensure
65
+ @serv.accept.close
66
+ end
67
+ errors.string.should.start_with? '[RequestReplay] Error:'
68
+ end
69
+
70
+ should 'not affect Rack::Request' do
71
+ input = StringIO.new('a=0&b=1')
72
+ e = {'rack.input' => input, 'REQUEST_METHOD' => 'POST'}
73
+ t = request[e]
74
+ @serv.accept.close
75
+ t.join
76
+ Rack::Request.new(e).POST.should.eq('a' => '0', 'b' => '1')
77
+ end
78
+ end
metadata CHANGED
@@ -1,55 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: request-replay
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lin Jen-Shin (godfat)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-07 00:00:00.000000000 Z
11
+ date: 2014-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bacon
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: muack
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rack
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  description: Replay the request via Rack env
@@ -59,9 +59,9 @@ executables: []
59
59
  extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
- - .gitignore
63
- - .gitmodules
64
- - .travis.yml
62
+ - ".gitignore"
63
+ - ".gitmodules"
64
+ - ".travis.yml"
65
65
  - CHANGES.md
66
66
  - Gemfile
67
67
  - LICENSE
@@ -69,10 +69,14 @@ files:
69
69
  - Rakefile
70
70
  - lib/request-replay.rb
71
71
  - lib/request-replay/middleware.rb
72
+ - lib/request-replay/proxy.rb
73
+ - lib/request-replay/test.rb
72
74
  - request-replay.gemspec
73
- - task/.gitignore
75
+ - task/README.md
74
76
  - task/gemgem.rb
75
- - test/test_basic.rb
77
+ - test/test_middleware.rb
78
+ - test/test_proxy.rb
79
+ - test/test_request-replay.rb
76
80
  homepage: https://github.com/godfat/request-replay
77
81
  licenses:
78
82
  - Apache License 2.0
@@ -83,19 +87,21 @@ require_paths:
83
87
  - lib
84
88
  required_ruby_version: !ruby/object:Gem::Requirement
85
89
  requirements:
86
- - - '>='
90
+ - - ">="
87
91
  - !ruby/object:Gem::Version
88
92
  version: '0'
89
93
  required_rubygems_version: !ruby/object:Gem::Requirement
90
94
  requirements:
91
- - - '>='
95
+ - - ">="
92
96
  - !ruby/object:Gem::Version
93
97
  version: '0'
94
98
  requirements: []
95
99
  rubyforge_project:
96
- rubygems_version: 2.1.5
100
+ rubygems_version: 2.2.2
97
101
  signing_key:
98
102
  specification_version: 4
99
103
  summary: Replay the request via Rack env
100
104
  test_files:
101
- - test/test_basic.rb
105
+ - test/test_middleware.rb
106
+ - test/test_proxy.rb
107
+ - test/test_request-replay.rb
@@ -1 +0,0 @@
1
- *.rbc
@@ -1,178 +0,0 @@
1
-
2
- require 'bacon'
3
- require 'muack'
4
-
5
- Bacon.summary_on_exit
6
- include Muack::API
7
-
8
- module Kernel
9
- def eq? rhs
10
- self == rhs
11
- end
12
- end
13
-
14
- require 'request-replay'
15
- require 'rack'
16
-
17
- describe RequestReplay do
18
- host = 'localhost'.freeze
19
- port = 1024 + rand(2**16 - 1024)
20
- serv = TCPServer.new('localhost', port)
21
- hopt = "#{host}:#{port}".freeze
22
- env = {'REQUEST_METHOD' => 'GET',
23
- 'PATH_INFO' => '/', 'QUERY_STRING' => 'q=1',
24
- 'HTTP_HOST' => 'localhost',
25
- 'HTTP_PORK' => 'BEEF' }.freeze
26
-
27
- verify = lambda do |response, expected|
28
- sock = serv.accept
29
- sock.read .should.eq(expected)
30
- sock.write(expected)
31
- sock.close
32
- response.value.should.eq(expected)
33
- end
34
-
35
- request = lambda do |env1, headers={}, read_wait=nil|
36
- Thread.new(RequestReplay.new(env.merge(env1), hopt,
37
- :add_headers => headers,
38
- :read_wait => read_wait)) do |replay|
39
- replay.start(&:read)
40
- end
41
- end
42
-
43
- after do
44
- Muack.verify
45
- end
46
-
47
- should 'GET' do
48
- verify[request[{'REQUEST_METHOD' => 'GET'}, 'Host' => 'ex.com'], <<-HTTP]
49
- GET /?q=1 HTTP/1.1\r
50
- Host: ex.com\r
51
- Pork: BEEF\r
52
- \r
53
- HTTP
54
- end
55
-
56
- should 'POST' do
57
- verify[request['REQUEST_METHOD' => 'POST',
58
- 'QUERY_STRING' => '' , # test no query string
59
- 'PATH_INFO' => '' , # test no path info
60
- 'rack.input' => StringIO.new("PAYLOAD\r\n\r\n")], <<-HTTP]
61
- POST / HTTP/1.1\r
62
- Host: localhost\r
63
- Pork: BEEF\r
64
- \r
65
- PAYLOAD\r
66
- \r
67
- HTTP
68
- end
69
-
70
- should 'read_wait' do
71
- read_wait = 5
72
- mock(IO).select(satisfy{ |rs| rs.size == 1 &&
73
- rs[0].kind_of?(IO) },
74
- [], [], read_wait)
75
-
76
- verify[request[{}, {}, read_wait], <<-HTTP]
77
- GET /?q=1 HTTP/1.1\r
78
- Host: localhost\r
79
- Pork: BEEF\r
80
- \r
81
- HTTP
82
- end
83
-
84
- should 'puts error' do
85
- any_instance_of(TCPSocket) do |sock|
86
- mock(sock).read{ raise 'ERROR' }
87
- end
88
-
89
- errors = StringIO.new
90
- begin
91
- request['rack.errors' => errors].value
92
- ensure
93
- serv.accept.close
94
- end
95
- errors.string.should.start_with? '[RequestReplay] Error:'
96
- end
97
-
98
- should 'not affect Rack::Request' do
99
- input = StringIO.new('a=0&b=1')
100
- e = {'rack.input' => input, 'REQUEST_METHOD' => 'POST'}
101
- t = request[e]
102
- serv.accept.close
103
- t.join
104
- Rack::Request.new(e).POST.should.eq('a' => '0', 'b' => '1')
105
- end
106
-
107
- describe RequestReplay::Middleware do
108
- should 'PUT' do
109
- app = Rack::Builder.app do
110
- use RequestReplay::Middleware, hopt
111
- run lambda{ |env| [200, {}, []] }
112
- end
113
-
114
- app.call(env.merge('REQUEST_METHOD' => 'PUT'))
115
- begin
116
- sock = serv.accept
117
- sock.read.should.eq <<-HTTP
118
- PUT /?q=1 HTTP/1.1\r
119
- Host: localhost\r
120
- Pork: BEEF\r
121
- \r
122
- HTTP
123
- ensure
124
- sock.close
125
- end
126
- end
127
-
128
- should 'retain original env' do
129
- e = env.dup
130
-
131
- app = Rack::Builder.app do
132
- use RequestReplay::Middleware, hopt
133
- run lambda{ |env|
134
- env['PATH_INFO'] = '/bad'
135
- [200, {}, []]
136
- }
137
- end
138
-
139
- app.call(e)
140
- begin
141
- sock = serv.accept
142
- sock.read.should.eq <<-HTTP
143
- GET /?q=1 HTTP/1.1\r
144
- Host: localhost\r
145
- Pork: BEEF\r
146
- \r
147
- HTTP
148
- ensure
149
- sock.close
150
- end
151
- end
152
-
153
- should 'rewrite_env' do
154
- app = Rack::Builder.app do
155
- use RequestReplay::Middleware, hopt, :rewrite_env => lambda{ |env|
156
- if env['HTTP_HOST'].start_with?('api.')
157
- env['PATH_INFO'] = "/api#{env['PATH_INFO']}"
158
- end
159
- env
160
- }, :add_headers => {'Host' => 'eg.com'}
161
- run lambda{ |env| [200, {}, []] }
162
- end
163
-
164
- app.call(env.merge('HTTP_HOST' => 'api.localhost'))
165
- begin
166
- sock = serv.accept
167
- sock.read.should.eq <<-HTTP
168
- GET /api/?q=1 HTTP/1.1\r
169
- Host: eg.com\r
170
- Pork: BEEF\r
171
- \r
172
- HTTP
173
- ensure
174
- sock.close
175
- end
176
- end
177
- end
178
- end