request-replay 0.6.3 → 0.7.0

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: 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