mdub-sham_rack 1.0.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.
- data/README.markdown +69 -0
- data/Rakefile +22 -0
- data/VERSION.yml +4 -0
- data/lib/sham_rack/core_ext/net/http.rb +17 -0
- data/lib/sham_rack/http.rb +106 -0
- data/lib/sham_rack/registry.rb +45 -0
- data/lib/sham_rack.rb +1 -0
- data/spec/sham_rack_spec.rb +214 -0
- data/spec/spec_helper.rb +12 -0
- metadata +62 -0
data/README.markdown
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
ShamRack
|
|
2
|
+
========
|
|
3
|
+
|
|
4
|
+
ShamRack plumbs Net:HTTP into [Rack][rack], providing infrastructure for testing arbitrary Rack-based apps using arbitrary HTTP clients, all from the comfort of your own Ruby VM.
|
|
5
|
+
|
|
6
|
+
What's it for, again?
|
|
7
|
+
---------------------
|
|
8
|
+
|
|
9
|
+
Well, you can _test your HTTP client code_, using ShamRack to fake out an external web-service ([Sinatra][sinatra] helps, here).
|
|
10
|
+
|
|
11
|
+
Or, you can `ShamRack.mount` your actual Sinatra/Rails/Merb/Rack app, which is handy if you want to _test access using an HTTP client library_ such as:
|
|
12
|
+
|
|
13
|
+
* [`rest-client`][rest-client]
|
|
14
|
+
* [`httparty`][httparty]
|
|
15
|
+
* [`oauth`][oauth]
|
|
16
|
+
|
|
17
|
+
Installing it
|
|
18
|
+
-------------
|
|
19
|
+
|
|
20
|
+
gem sources -a http://gems.github.com
|
|
21
|
+
sudo gem install mdub-sham_rack
|
|
22
|
+
|
|
23
|
+
Using it
|
|
24
|
+
--------
|
|
25
|
+
|
|
26
|
+
require 'sham_rack'
|
|
27
|
+
|
|
28
|
+
rack_app = lambda { |env| ["200 OK", { "Content-type" => "text/plain" }, "Hello, world!"] }
|
|
29
|
+
ShamRack.mount(rack_app, "www.example.com")
|
|
30
|
+
|
|
31
|
+
require 'open-uri'
|
|
32
|
+
open("http://www.example.com/").read #=> "Hello, world!"
|
|
33
|
+
|
|
34
|
+
### Sinatra integration
|
|
35
|
+
|
|
36
|
+
ShamRack.sinatra("sinatra.xyz") do
|
|
37
|
+
get "/hello/:subject" do
|
|
38
|
+
"Hello, #{params[:subject]}"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
open("http://sinatra.xyz/hello/stranger").read #=> "Hello, stranger"
|
|
43
|
+
|
|
44
|
+
### Rackup support
|
|
45
|
+
|
|
46
|
+
ShamRack.rackup("rackup.xyz") do
|
|
47
|
+
use Some::Middleware
|
|
48
|
+
use Some::Other::Middleware
|
|
49
|
+
run MyApp.new
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
What's the catch?
|
|
53
|
+
-----------------
|
|
54
|
+
|
|
55
|
+
* It's brand new! (there will be dragons)
|
|
56
|
+
* Your Rack request-handling code runs in the same Ruby VM, in fact the same Thread, as your request.
|
|
57
|
+
|
|
58
|
+
Thanks to
|
|
59
|
+
---------
|
|
60
|
+
|
|
61
|
+
* Blaine Cook for [FakeWeb][fakeweb], which was an inspiration for ShamRack.
|
|
62
|
+
* Christian Neukirchen et al for the chewy goodness that is [Rack][rack].
|
|
63
|
+
|
|
64
|
+
[rack]: http://rack.rubyforge.org/
|
|
65
|
+
[sinatra]: http://www.sinatrarb.com/
|
|
66
|
+
[rest-client]: http://github.com/adamwiggins/rest-client
|
|
67
|
+
[httparty]: http://github.com/jnunemaker/httparty
|
|
68
|
+
[oauth]: http://oauth.rubyforge.org/
|
|
69
|
+
[fakeweb]: http://fakeweb.rubyforge.org/
|
data/Rakefile
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require "spec/rake/spectask"
|
|
2
|
+
|
|
3
|
+
task "default" => "spec"
|
|
4
|
+
|
|
5
|
+
Spec::Rake::SpecTask.new do |t|
|
|
6
|
+
t.spec_opts = ["--colour", "--format", "progress"]
|
|
7
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
begin
|
|
11
|
+
require 'jeweler'
|
|
12
|
+
Jeweler::Tasks.new do |gemspec|
|
|
13
|
+
gemspec.name = "sham_rack"
|
|
14
|
+
gemspec.summary = "Net::HTTP-to-Rack plumbing"
|
|
15
|
+
gemspec.email = "mdub@dogbiscuit.org"
|
|
16
|
+
gemspec.homepage = "http://github.com/mdub/sham_rack"
|
|
17
|
+
gemspec.description = "ShamRack plumbs Net::HTTP directly into Rack, for quick and easy HTTP testing."
|
|
18
|
+
gemspec.authors = ["Mike Williams"]
|
|
19
|
+
end
|
|
20
|
+
rescue LoadError
|
|
21
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
|
22
|
+
end
|
data/VERSION.yml
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require "net/http"
|
|
2
|
+
require "sham_rack/registry"
|
|
3
|
+
require "sham_rack/http"
|
|
4
|
+
|
|
5
|
+
module Net
|
|
6
|
+
|
|
7
|
+
def HTTP.new(address, port = nil, *proxy_args)
|
|
8
|
+
port ||= HTTP.default_port
|
|
9
|
+
rack_app = ShamRack.application_for(address, port)
|
|
10
|
+
if rack_app
|
|
11
|
+
ShamRack::HTTP.new(address, port, rack_app)
|
|
12
|
+
else
|
|
13
|
+
super(address, port, *proxy_args)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
module ShamRack
|
|
2
|
+
|
|
3
|
+
# a sham version of Net::HTTP
|
|
4
|
+
class HTTP
|
|
5
|
+
|
|
6
|
+
def initialize(address, port, rack_app)
|
|
7
|
+
@address = address
|
|
8
|
+
@port = port
|
|
9
|
+
@rack_app = rack_app
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def start
|
|
13
|
+
yield self
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
attr_accessor :use_ssl, :verify_mode, :read_timeout, :open_timeout
|
|
17
|
+
|
|
18
|
+
def request(req, body = nil)
|
|
19
|
+
env = default_env
|
|
20
|
+
env.merge!(path_env(req.path))
|
|
21
|
+
env.merge!(method_env(req))
|
|
22
|
+
env.merge!(header_env(req))
|
|
23
|
+
env.merge!(io_env(req, body))
|
|
24
|
+
response = build_response(@rack_app.call(env))
|
|
25
|
+
yield response if block_given?
|
|
26
|
+
return response
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def default_env
|
|
32
|
+
{
|
|
33
|
+
"SCRIPT_NAME" => "",
|
|
34
|
+
"SERVER_NAME" => @address,
|
|
35
|
+
"SERVER_PORT" => @port.to_s,
|
|
36
|
+
"rack.version" => [0,1],
|
|
37
|
+
"rack.url_scheme" => "http",
|
|
38
|
+
"rack.multithread" => true,
|
|
39
|
+
"rack.multiprocess" => true,
|
|
40
|
+
"rack.run_once" => false
|
|
41
|
+
}
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def method_env(request)
|
|
45
|
+
{
|
|
46
|
+
"REQUEST_METHOD" => request.method
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def io_env(request, body)
|
|
51
|
+
raise(ArgumentError, "both request.body and body argument were provided") if (request.body && body)
|
|
52
|
+
body ||= request.body || ""
|
|
53
|
+
{
|
|
54
|
+
"rack.input" => StringIO.new(body),
|
|
55
|
+
"rack.errors" => $stderr
|
|
56
|
+
}
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def path_env(path)
|
|
60
|
+
uri = URI.parse(path)
|
|
61
|
+
{
|
|
62
|
+
"PATH_INFO" => uri.path,
|
|
63
|
+
"QUERY_STRING" => (uri.query || ""),
|
|
64
|
+
}
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def header_env(request)
|
|
68
|
+
result = {}
|
|
69
|
+
request.each do |header, content|
|
|
70
|
+
result["HTTP_" + header.upcase.gsub('-', '_')] = content
|
|
71
|
+
end
|
|
72
|
+
%w(TYPE LENGTH).each do |x|
|
|
73
|
+
result["CONTENT_#{x}"] = result.delete("HTTP_CONTENT_#{x}") if result.has_key?("HTTP_CONTENT_#{x}")
|
|
74
|
+
end
|
|
75
|
+
return result
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def build_response(rack_response)
|
|
79
|
+
status, headers, body = rack_response
|
|
80
|
+
code, message = status.to_s.split(" ", 2)
|
|
81
|
+
response = Net::HTTPResponse.send(:response_class, code).new("Sham", code, message)
|
|
82
|
+
response.instance_variable_set(:@body, assemble_body(body))
|
|
83
|
+
response.instance_variable_set(:@read, true)
|
|
84
|
+
response.extend ShamRack::ResponseExtensions
|
|
85
|
+
return response
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def assemble_body(body)
|
|
89
|
+
content = ""
|
|
90
|
+
body.each { |fragment| content << fragment }
|
|
91
|
+
return content
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
module ResponseExtensions
|
|
97
|
+
|
|
98
|
+
def read_body(dest = nil)
|
|
99
|
+
yield @body if block_given?
|
|
100
|
+
dest << @body if dest
|
|
101
|
+
return @body
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module ShamRack
|
|
2
|
+
|
|
3
|
+
module Registry
|
|
4
|
+
|
|
5
|
+
def mount(rack_app, address, port = nil)
|
|
6
|
+
port ||= Net::HTTP.default_port
|
|
7
|
+
registry[[address, port]] = rack_app
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def rackup(address, port = nil, &block)
|
|
11
|
+
app = Rack::Builder.new(&block).to_app
|
|
12
|
+
mount(app, address, port)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def lambda(address, port = nil, &block)
|
|
16
|
+
mount(block, address, port)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def sinatra(address, port = nil, &block)
|
|
20
|
+
require "sinatra/base"
|
|
21
|
+
sinatra_app = Class.new(Sinatra::Base)
|
|
22
|
+
sinatra_app.class_eval(&block)
|
|
23
|
+
mount(sinatra_app.new, address, port)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def unmount_all
|
|
27
|
+
registry.clear
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def application_for(address, port = nil)
|
|
31
|
+
port ||= Net::HTTP.default_port
|
|
32
|
+
registry[[address, port]]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def registry
|
|
38
|
+
@registry ||= {}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
extend Registry
|
|
44
|
+
|
|
45
|
+
end
|
data/lib/sham_rack.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "sham_rack/core_ext/net/http"
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
|
+
|
|
3
|
+
require "sham_rack"
|
|
4
|
+
require "open-uri"
|
|
5
|
+
require "restclient"
|
|
6
|
+
require "rack"
|
|
7
|
+
|
|
8
|
+
class PlainTextApp
|
|
9
|
+
|
|
10
|
+
def call(env)
|
|
11
|
+
[
|
|
12
|
+
"200 OK",
|
|
13
|
+
{ "Content-Type" => "text/plain", "Content-Length" => message.length.to_s },
|
|
14
|
+
[message]
|
|
15
|
+
]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class SimpleMessageApp < PlainTextApp
|
|
21
|
+
|
|
22
|
+
def initialize(message)
|
|
23
|
+
@message = message
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
attr_reader :message
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class EnvRecordingApp < PlainTextApp
|
|
31
|
+
|
|
32
|
+
def call(env)
|
|
33
|
+
@last_env = env
|
|
34
|
+
super
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
attr_reader :last_env
|
|
38
|
+
|
|
39
|
+
def message
|
|
40
|
+
"env stored for later perusal"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class UpcaseBody
|
|
46
|
+
|
|
47
|
+
def initialize(app)
|
|
48
|
+
@app = app
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def call(env)
|
|
52
|
+
status, headers, body = @app.call(env)
|
|
53
|
+
upcased_body = Array(body).map { |x| x.upcase }
|
|
54
|
+
[status, headers, upcased_body]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe ShamRack do
|
|
60
|
+
|
|
61
|
+
after(:each) do
|
|
62
|
+
ShamRack.unmount_all
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe "mounted Rack application" do
|
|
66
|
+
|
|
67
|
+
before(:each) do
|
|
68
|
+
ShamRack.mount(SimpleMessageApp.new("Hello, world"), "www.test.xyz")
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "can be accessed using Net::HTTP" do
|
|
72
|
+
response = Net::HTTP.start("www.test.xyz") do |http|
|
|
73
|
+
http.request(Net::HTTP::Get.new("/"))
|
|
74
|
+
end
|
|
75
|
+
response.body.should == "Hello, world"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "can be accessed using open-uri" do
|
|
79
|
+
response = open("http://www.test.xyz")
|
|
80
|
+
response.status.should == ["200", "OK"]
|
|
81
|
+
response.read.should == "Hello, world"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "can be accessed using RestClient" do
|
|
85
|
+
response = RestClient.get("http://www.test.xyz")
|
|
86
|
+
response.code.should == 200
|
|
87
|
+
response.to_s.should == "Hello, world"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
describe "#rackup" do
|
|
93
|
+
|
|
94
|
+
it "mounts an app created using Rack::Builder" do
|
|
95
|
+
|
|
96
|
+
ShamRack.rackup("rackup.xyz") do
|
|
97
|
+
use UpcaseBody
|
|
98
|
+
run SimpleMessageApp.new("Racked!")
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
open("http://rackup.xyz").read.should == "RACKED!"
|
|
102
|
+
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe "#lambda" do
|
|
108
|
+
|
|
109
|
+
it "mounts associated block as an app" do
|
|
110
|
+
|
|
111
|
+
ShamRack.lambda("simple.xyz") do |env|
|
|
112
|
+
["200 OK", { "Content-type" => "text/plain" }, "Easy, huh?"]
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
open("http://simple.xyz").read.should == "Easy, huh?"
|
|
116
|
+
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
describe "#sinatra" do
|
|
122
|
+
|
|
123
|
+
it "mounts associated block as a Sinatra app" do
|
|
124
|
+
|
|
125
|
+
ShamRack.sinatra("sinatra.xyz") do
|
|
126
|
+
get "/hello/:subject" do
|
|
127
|
+
"Hello, #{params[:subject]}"
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
open("http://sinatra.xyz/hello/stranger").read.should == "Hello, stranger"
|
|
132
|
+
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
describe "Rack environment" do
|
|
138
|
+
|
|
139
|
+
before(:each) do
|
|
140
|
+
@env_recorder = recorder = EnvRecordingApp.new
|
|
141
|
+
ShamRack.rackup("env.xyz") do
|
|
142
|
+
use Rack::Lint
|
|
143
|
+
run recorder
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def env
|
|
148
|
+
@env_recorder.last_env
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "is valid" do
|
|
152
|
+
|
|
153
|
+
open("http://env.xyz/blah?q=abc")
|
|
154
|
+
|
|
155
|
+
env["REQUEST_METHOD"].should == "GET"
|
|
156
|
+
env["SCRIPT_NAME"].should == ""
|
|
157
|
+
env["PATH_INFO"].should == "/blah"
|
|
158
|
+
env["QUERY_STRING"].should == "q=abc"
|
|
159
|
+
env["SERVER_NAME"].should == "env.xyz"
|
|
160
|
+
env["SERVER_PORT"].should == "80"
|
|
161
|
+
|
|
162
|
+
env["rack.version"].should == [0,1]
|
|
163
|
+
env["rack.url_scheme"].should == "http"
|
|
164
|
+
|
|
165
|
+
env["rack.multithread"].should == true
|
|
166
|
+
env["rack.multiprocess"].should == true
|
|
167
|
+
env["rack.run_once"].should == false
|
|
168
|
+
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it "provides request headers" do
|
|
172
|
+
|
|
173
|
+
Net::HTTP.start("env.xyz") do |http|
|
|
174
|
+
request = Net::HTTP::Get.new("/")
|
|
175
|
+
request["Foo-bar"] = "baz"
|
|
176
|
+
http.request(request)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
env["HTTP_FOO_BAR"].should == "baz"
|
|
180
|
+
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it "supports POST" do
|
|
184
|
+
|
|
185
|
+
RestClient.post("http://env.xyz/resource", "q" => "rack")
|
|
186
|
+
|
|
187
|
+
env["REQUEST_METHOD"].should == "POST"
|
|
188
|
+
env["CONTENT_TYPE"].should == "application/x-www-form-urlencoded"
|
|
189
|
+
env["rack.input"].read.should == "q=rack"
|
|
190
|
+
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it "supports PUT" do
|
|
194
|
+
|
|
195
|
+
RestClient.put("http://env.xyz/thing1", "stuff", :content_type => "text/plain")
|
|
196
|
+
|
|
197
|
+
env["REQUEST_METHOD"].should == "PUT"
|
|
198
|
+
env["CONTENT_TYPE"].should == "text/plain"
|
|
199
|
+
env["rack.input"].read.should == "stuff"
|
|
200
|
+
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
it "supports DELETE" do
|
|
204
|
+
|
|
205
|
+
RestClient.delete("http://env.xyz/thing/1")
|
|
206
|
+
|
|
207
|
+
env["REQUEST_METHOD"].should == "DELETE"
|
|
208
|
+
env["PATH_INFO"].should == "/thing/1"
|
|
209
|
+
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require "rubygems"
|
|
2
|
+
require "spec"
|
|
3
|
+
require "rr"
|
|
4
|
+
require "ruby-debug"
|
|
5
|
+
|
|
6
|
+
project_root = File.expand_path("#{__FILE__}/../..")
|
|
7
|
+
$LOAD_PATH << "#{project_root}/lib"
|
|
8
|
+
$LOAD_PATH << "#{project_root}/spec/support/lib"
|
|
9
|
+
|
|
10
|
+
Spec::Runner.configure do |config|
|
|
11
|
+
config.mock_with RR::Adapters::Rspec
|
|
12
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: mdub-sham_rack
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Mike Williams
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2009-05-06 00:00:00 -07:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies: []
|
|
15
|
+
|
|
16
|
+
description: ShamRack plumbs Net::HTTP directly into Rack, for quick and easy HTTP testing.
|
|
17
|
+
email: mdub@dogbiscuit.org
|
|
18
|
+
executables: []
|
|
19
|
+
|
|
20
|
+
extensions: []
|
|
21
|
+
|
|
22
|
+
extra_rdoc_files:
|
|
23
|
+
- README.markdown
|
|
24
|
+
files:
|
|
25
|
+
- README.markdown
|
|
26
|
+
- Rakefile
|
|
27
|
+
- VERSION.yml
|
|
28
|
+
- lib/sham_rack.rb
|
|
29
|
+
- lib/sham_rack/core_ext/net/http.rb
|
|
30
|
+
- lib/sham_rack/http.rb
|
|
31
|
+
- lib/sham_rack/registry.rb
|
|
32
|
+
- spec/sham_rack_spec.rb
|
|
33
|
+
- spec/spec_helper.rb
|
|
34
|
+
has_rdoc: true
|
|
35
|
+
homepage: http://github.com/mdub/sham_rack
|
|
36
|
+
post_install_message:
|
|
37
|
+
rdoc_options:
|
|
38
|
+
- --charset=UTF-8
|
|
39
|
+
require_paths:
|
|
40
|
+
- lib
|
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
42
|
+
requirements:
|
|
43
|
+
- - ">="
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: "0"
|
|
46
|
+
version:
|
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
48
|
+
requirements:
|
|
49
|
+
- - ">="
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: "0"
|
|
52
|
+
version:
|
|
53
|
+
requirements: []
|
|
54
|
+
|
|
55
|
+
rubyforge_project:
|
|
56
|
+
rubygems_version: 1.2.0
|
|
57
|
+
signing_key:
|
|
58
|
+
specification_version: 3
|
|
59
|
+
summary: Net::HTTP-to-Rack plumbing
|
|
60
|
+
test_files:
|
|
61
|
+
- spec/sham_rack_spec.rb
|
|
62
|
+
- spec/spec_helper.rb
|