lack 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/bin/rackup +5 -0
  3. data/lib/rack.rb +26 -0
  4. data/lib/rack/body_proxy.rb +39 -0
  5. data/lib/rack/builder.rb +166 -0
  6. data/lib/rack/handler.rb +63 -0
  7. data/lib/rack/handler/webrick.rb +120 -0
  8. data/lib/rack/mime.rb +661 -0
  9. data/lib/rack/mock.rb +198 -0
  10. data/lib/rack/multipart.rb +31 -0
  11. data/lib/rack/multipart/generator.rb +93 -0
  12. data/lib/rack/multipart/parser.rb +239 -0
  13. data/lib/rack/multipart/uploaded_file.rb +34 -0
  14. data/lib/rack/request.rb +394 -0
  15. data/lib/rack/response.rb +160 -0
  16. data/lib/rack/server.rb +258 -0
  17. data/lib/rack/server/options.rb +121 -0
  18. data/lib/rack/utils.rb +653 -0
  19. data/lib/rack/version.rb +3 -0
  20. data/spec/spec_helper.rb +1 -0
  21. data/test/builder/anything.rb +5 -0
  22. data/test/builder/comment.ru +4 -0
  23. data/test/builder/end.ru +5 -0
  24. data/test/builder/line.ru +1 -0
  25. data/test/builder/options.ru +2 -0
  26. data/test/multipart/bad_robots +259 -0
  27. data/test/multipart/binary +0 -0
  28. data/test/multipart/content_type_and_no_filename +6 -0
  29. data/test/multipart/empty +10 -0
  30. data/test/multipart/fail_16384_nofile +814 -0
  31. data/test/multipart/file1.txt +1 -0
  32. data/test/multipart/filename_and_modification_param +7 -0
  33. data/test/multipart/filename_and_no_name +6 -0
  34. data/test/multipart/filename_with_escaped_quotes +6 -0
  35. data/test/multipart/filename_with_escaped_quotes_and_modification_param +7 -0
  36. data/test/multipart/filename_with_percent_escaped_quotes +6 -0
  37. data/test/multipart/filename_with_unescaped_percentages +6 -0
  38. data/test/multipart/filename_with_unescaped_percentages2 +6 -0
  39. data/test/multipart/filename_with_unescaped_percentages3 +6 -0
  40. data/test/multipart/filename_with_unescaped_quotes +6 -0
  41. data/test/multipart/ie +6 -0
  42. data/test/multipart/invalid_character +6 -0
  43. data/test/multipart/mixed_files +21 -0
  44. data/test/multipart/nested +10 -0
  45. data/test/multipart/none +9 -0
  46. data/test/multipart/semicolon +6 -0
  47. data/test/multipart/text +15 -0
  48. data/test/multipart/webkit +32 -0
  49. data/test/rackup/config.ru +31 -0
  50. data/test/registering_handler/rack/handler/registering_myself.rb +8 -0
  51. data/test/spec_body_proxy.rb +69 -0
  52. data/test/spec_builder.rb +223 -0
  53. data/test/spec_chunked.rb +101 -0
  54. data/test/spec_file.rb +221 -0
  55. data/test/spec_handler.rb +59 -0
  56. data/test/spec_head.rb +45 -0
  57. data/test/spec_lint.rb +522 -0
  58. data/test/spec_mime.rb +51 -0
  59. data/test/spec_mock.rb +277 -0
  60. data/test/spec_multipart.rb +547 -0
  61. data/test/spec_recursive.rb +72 -0
  62. data/test/spec_request.rb +1199 -0
  63. data/test/spec_response.rb +343 -0
  64. data/test/spec_rewindable_input.rb +118 -0
  65. data/test/spec_sendfile.rb +130 -0
  66. data/test/spec_server.rb +167 -0
  67. data/test/spec_utils.rb +635 -0
  68. data/test/spec_webrick.rb +184 -0
  69. data/test/testrequest.rb +78 -0
  70. data/test/unregistered_handler/rack/handler/unregistered.rb +7 -0
  71. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +7 -0
  72. metadata +240 -0
@@ -0,0 +1,184 @@
1
+ require 'rack/mock'
2
+ require File.expand_path('../testrequest', __FILE__)
3
+
4
+ Thread.abort_on_exception = true
5
+
6
+ describe Rack::Handler::WEBrick do
7
+ extend TestRequest::Helpers
8
+
9
+ @server = WEBrick::HTTPServer.new(:Host => @host='127.0.0.1',
10
+ :Port => @port=9202,
11
+ :Logger => WEBrick::Log.new(nil, WEBrick::BasicLog::WARN),
12
+ :AccessLog => [])
13
+ @server.mount "/test", Rack::Handler::WEBrick,
14
+ Rack::Lint.new(TestRequest.new)
15
+ Thread.new { @server.start }
16
+ trap(:INT) { @server.shutdown }
17
+
18
+ should "respond" do
19
+ lambda {
20
+ GET("/test")
21
+ }.should.not.raise
22
+ end
23
+
24
+ should "be a WEBrick" do
25
+ GET("/test")
26
+ status.should.equal 200
27
+ response["SERVER_SOFTWARE"].should =~ /WEBrick/
28
+ response["HTTP_VERSION"].should.equal "HTTP/1.1"
29
+ response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
30
+ response["SERVER_PORT"].should.equal "9202"
31
+ response["SERVER_NAME"].should.equal "127.0.0.1"
32
+ end
33
+
34
+ should "have rack headers" do
35
+ GET("/test")
36
+ response["rack.version"].should.equal [1,2]
37
+ response["rack.multithread"].should.be.true
38
+ response["rack.multiprocess"].should.be.false
39
+ response["rack.run_once"].should.be.false
40
+ end
41
+
42
+ should "have CGI headers on GET" do
43
+ GET("/test")
44
+ response["REQUEST_METHOD"].should.equal "GET"
45
+ response["SCRIPT_NAME"].should.equal "/test"
46
+ response["REQUEST_PATH"].should.equal "/test"
47
+ response["PATH_INFO"].should.be.equal ""
48
+ response["QUERY_STRING"].should.equal ""
49
+ response["test.postdata"].should.equal ""
50
+
51
+ GET("/test/foo?quux=1")
52
+ response["REQUEST_METHOD"].should.equal "GET"
53
+ response["SCRIPT_NAME"].should.equal "/test"
54
+ response["REQUEST_PATH"].should.equal "/test/foo"
55
+ response["PATH_INFO"].should.equal "/foo"
56
+ response["QUERY_STRING"].should.equal "quux=1"
57
+
58
+ GET("/test/foo%25encoding?quux=1")
59
+ response["REQUEST_METHOD"].should.equal "GET"
60
+ response["SCRIPT_NAME"].should.equal "/test"
61
+ response["REQUEST_PATH"].should.equal "/test/foo%25encoding"
62
+ response["PATH_INFO"].should.equal "/foo%25encoding"
63
+ response["QUERY_STRING"].should.equal "quux=1"
64
+ end
65
+
66
+ should "have CGI headers on POST" do
67
+ POST("/test", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
68
+ status.should.equal 200
69
+ response["REQUEST_METHOD"].should.equal "POST"
70
+ response["SCRIPT_NAME"].should.equal "/test"
71
+ response["REQUEST_PATH"].should.equal "/test"
72
+ response["PATH_INFO"].should.equal ""
73
+ response["QUERY_STRING"].should.equal ""
74
+ response["HTTP_X_TEST_HEADER"].should.equal "42"
75
+ response["test.postdata"].should.equal "rack-form-data=23"
76
+ end
77
+
78
+ should "support HTTP auth" do
79
+ GET("/test", {:user => "ruth", :passwd => "secret"})
80
+ response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ="
81
+ end
82
+
83
+ should "set status" do
84
+ GET("/test?secret")
85
+ status.should.equal 403
86
+ response["rack.url_scheme"].should.equal "http"
87
+ end
88
+
89
+ should "correctly set cookies" do
90
+ @server.mount "/cookie-test", Rack::Handler::WEBrick,
91
+ Rack::Lint.new(lambda { |req|
92
+ res = Rack::Response.new
93
+ res.set_cookie "one", "1"
94
+ res.set_cookie "two", "2"
95
+ res.finish
96
+ })
97
+
98
+ Net::HTTP.start(@host, @port) { |http|
99
+ res = http.get("/cookie-test")
100
+ res.code.to_i.should.equal 200
101
+ res.get_fields("set-cookie").should.equal ["one=1", "two=2"]
102
+ }
103
+ end
104
+
105
+ should "provide a .run" do
106
+ block_ran = false
107
+ catch(:done) {
108
+ Rack::Handler::WEBrick.run(lambda {},
109
+ {
110
+ :Host => '127.0.0.1',
111
+ :Port => 9210,
112
+ :Logger => WEBrick::Log.new(nil, WEBrick::BasicLog::WARN),
113
+ :AccessLog => []}) { |server|
114
+ block_ran = true
115
+ server.should.be.kind_of WEBrick::HTTPServer
116
+ @s = server
117
+ throw :done
118
+ }
119
+ }
120
+ block_ran.should.be.true
121
+ @s.shutdown
122
+ end
123
+
124
+ should "return repeated headers" do
125
+ @server.mount "/headers", Rack::Handler::WEBrick,
126
+ Rack::Lint.new(lambda { |req|
127
+ [
128
+ 401,
129
+ { "Content-Type" => "text/plain",
130
+ "WWW-Authenticate" => "Bar realm=X\nBaz realm=Y" },
131
+ [""]
132
+ ]
133
+ })
134
+
135
+ Net::HTTP.start(@host, @port) { |http|
136
+ res = http.get("/headers")
137
+ res.code.to_i.should.equal 401
138
+ res["www-authenticate"].should.equal "Bar realm=X, Baz realm=Y"
139
+ }
140
+ end
141
+
142
+ should "support Rack partial hijack" do
143
+ io_lambda = lambda{ |io|
144
+ 5.times do
145
+ io.write "David\r\n"
146
+ end
147
+ io.close
148
+ }
149
+
150
+ @server.mount "/partial", Rack::Handler::WEBrick,
151
+ Rack::Lint.new(lambda{ |req|
152
+ [
153
+ 200,
154
+ {"rack.hijack" => io_lambda},
155
+ [""]
156
+ ]
157
+ })
158
+
159
+ Net::HTTP.start(@host, @port){ |http|
160
+ res = http.get("/partial")
161
+ res.body.should.equal "David\r\nDavid\r\nDavid\r\nDavid\r\nDavid\r\n"
162
+ }
163
+ end
164
+
165
+ should "produce correct HTTP semantics with and without app chunking" do
166
+ @server.mount "/chunked", Rack::Handler::WEBrick,
167
+ Rack::Lint.new(lambda{ |req|
168
+ [
169
+ 200,
170
+ {"Transfer-Encoding" => "chunked"},
171
+ ["7\r\nchunked\r\n0\r\n\r\n"]
172
+ ]
173
+ })
174
+
175
+ Net::HTTP.start(@host, @port){ |http|
176
+ res = http.get("/chunked")
177
+ res["Transfer-Encoding"].should.equal "chunked"
178
+ res["Content-Length"].should.equal nil
179
+ res.body.should.equal "chunked"
180
+ }
181
+ end
182
+
183
+ @server.shutdown
184
+ end
@@ -0,0 +1,78 @@
1
+ require 'yaml'
2
+ require 'net/http'
3
+ require 'rack/lint'
4
+
5
+ class TestRequest
6
+ NOSERIALIZE = [Method, Proc, Rack::Lint::InputWrapper]
7
+
8
+ def call(env)
9
+ status = env["QUERY_STRING"] =~ /secret/ ? 403 : 200
10
+ env["test.postdata"] = env["rack.input"].read
11
+ minienv = env.dup
12
+ # This may in the future want to replace with a dummy value instead.
13
+ minienv.delete_if { |k,v| NOSERIALIZE.any? { |c| v.kind_of?(c) } }
14
+ body = minienv.to_yaml
15
+ size = body.respond_to?(:bytesize) ? body.bytesize : body.size
16
+ [status, {"Content-Type" => "text/yaml", "Content-Length" => size.to_s}, [body]]
17
+ end
18
+
19
+ module Helpers
20
+ attr_reader :status, :response
21
+
22
+ ROOT = File.expand_path(File.dirname(__FILE__) + "/..")
23
+ ENV["RUBYOPT"] = "-I#{ROOT}/lib -rubygems"
24
+
25
+ def root
26
+ ROOT
27
+ end
28
+
29
+ def rackup
30
+ "#{ROOT}/bin/rackup"
31
+ end
32
+
33
+ def GET(path, header={})
34
+ Net::HTTP.start(@host, @port) { |http|
35
+ user = header.delete(:user)
36
+ passwd = header.delete(:passwd)
37
+
38
+ get = Net::HTTP::Get.new(path, header)
39
+ get.basic_auth user, passwd if user && passwd
40
+ http.request(get) { |response|
41
+ @status = response.code.to_i
42
+ begin
43
+ @response = YAML.load(response.body)
44
+ rescue TypeError, ArgumentError
45
+ @response = nil
46
+ end
47
+ }
48
+ }
49
+ end
50
+
51
+ def POST(path, formdata={}, header={})
52
+ Net::HTTP.start(@host, @port) { |http|
53
+ user = header.delete(:user)
54
+ passwd = header.delete(:passwd)
55
+
56
+ post = Net::HTTP::Post.new(path, header)
57
+ post.form_data = formdata
58
+ post.basic_auth user, passwd if user && passwd
59
+ http.request(post) { |response|
60
+ @status = response.code.to_i
61
+ @response = YAML.load(response.body)
62
+ }
63
+ }
64
+ end
65
+ end
66
+ end
67
+
68
+ class StreamingRequest
69
+ def self.call(env)
70
+ [200, {"Content-Type" => "text/plain"}, new]
71
+ end
72
+
73
+ def each
74
+ yield "hello there!\n"
75
+ sleep 5
76
+ yield "that is all.\n"
77
+ end
78
+ end
@@ -0,0 +1,7 @@
1
+ module Rack
2
+ module Handler
3
+ # this class doesn't do anything, we're just seeing if we get it.
4
+ class Unregistered
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Rack
2
+ module Handler
3
+ # this class doesn't do anything, we're just seeing if we get it.
4
+ class UnregisteredLongOne
5
+ end
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,240 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lack
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Christian Neukirchen
8
+ - Kurtis Rainbolt-Greene
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-10-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.3'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.3'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rspec
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '3.0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '3.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '10.1'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '10.1'
56
+ - !ruby/object:Gem::Dependency
57
+ name: pry
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '0.9'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '0.9'
70
+ - !ruby/object:Gem::Dependency
71
+ name: pry-doc
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '0.6'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '0.6'
84
+ description: A modular Ruby webserver interface.
85
+ email:
86
+ - chneukirchen@gmail.com
87
+ - me@kurtisrainboltgreene.name
88
+ executables:
89
+ - rackup
90
+ extensions: []
91
+ extra_rdoc_files: []
92
+ files:
93
+ - bin/rackup
94
+ - lib/rack.rb
95
+ - lib/rack/body_proxy.rb
96
+ - lib/rack/builder.rb
97
+ - lib/rack/handler.rb
98
+ - lib/rack/handler/webrick.rb
99
+ - lib/rack/mime.rb
100
+ - lib/rack/mock.rb
101
+ - lib/rack/multipart.rb
102
+ - lib/rack/multipart/generator.rb
103
+ - lib/rack/multipart/parser.rb
104
+ - lib/rack/multipart/uploaded_file.rb
105
+ - lib/rack/request.rb
106
+ - lib/rack/response.rb
107
+ - lib/rack/server.rb
108
+ - lib/rack/server/options.rb
109
+ - lib/rack/utils.rb
110
+ - lib/rack/version.rb
111
+ - spec/spec_helper.rb
112
+ - test/builder/anything.rb
113
+ - test/builder/comment.ru
114
+ - test/builder/end.ru
115
+ - test/builder/line.ru
116
+ - test/builder/options.ru
117
+ - test/multipart/bad_robots
118
+ - test/multipart/binary
119
+ - test/multipart/content_type_and_no_filename
120
+ - test/multipart/empty
121
+ - test/multipart/fail_16384_nofile
122
+ - test/multipart/file1.txt
123
+ - test/multipart/filename_and_modification_param
124
+ - test/multipart/filename_and_no_name
125
+ - test/multipart/filename_with_escaped_quotes
126
+ - test/multipart/filename_with_escaped_quotes_and_modification_param
127
+ - test/multipart/filename_with_percent_escaped_quotes
128
+ - test/multipart/filename_with_unescaped_percentages
129
+ - test/multipart/filename_with_unescaped_percentages2
130
+ - test/multipart/filename_with_unescaped_percentages3
131
+ - test/multipart/filename_with_unescaped_quotes
132
+ - test/multipart/ie
133
+ - test/multipart/invalid_character
134
+ - test/multipart/mixed_files
135
+ - test/multipart/nested
136
+ - test/multipart/none
137
+ - test/multipart/semicolon
138
+ - test/multipart/text
139
+ - test/multipart/webkit
140
+ - test/rackup/config.ru
141
+ - test/registering_handler/rack/handler/registering_myself.rb
142
+ - test/spec_body_proxy.rb
143
+ - test/spec_builder.rb
144
+ - test/spec_chunked.rb
145
+ - test/spec_file.rb
146
+ - test/spec_handler.rb
147
+ - test/spec_head.rb
148
+ - test/spec_lint.rb
149
+ - test/spec_mime.rb
150
+ - test/spec_mock.rb
151
+ - test/spec_multipart.rb
152
+ - test/spec_recursive.rb
153
+ - test/spec_request.rb
154
+ - test/spec_response.rb
155
+ - test/spec_rewindable_input.rb
156
+ - test/spec_sendfile.rb
157
+ - test/spec_server.rb
158
+ - test/spec_utils.rb
159
+ - test/spec_webrick.rb
160
+ - test/testrequest.rb
161
+ - test/unregistered_handler/rack/handler/unregistered.rb
162
+ - test/unregistered_handler/rack/handler/unregistered_long_one.rb
163
+ homepage: http://krainboltgreene.github.io/lack
164
+ licenses:
165
+ - MIT
166
+ metadata: {}
167
+ post_install_message:
168
+ rdoc_options: []
169
+ require_paths:
170
+ - lib
171
+ required_ruby_version: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ required_rubygems_version: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ requirements: []
182
+ rubyforge_project:
183
+ rubygems_version: 2.2.2
184
+ signing_key:
185
+ specification_version: 4
186
+ summary: A modular Ruby webserver interface.
187
+ test_files:
188
+ - test/builder/anything.rb
189
+ - test/builder/comment.ru
190
+ - test/builder/end.ru
191
+ - test/builder/line.ru
192
+ - test/builder/options.ru
193
+ - test/multipart/bad_robots
194
+ - test/multipart/binary
195
+ - test/multipart/content_type_and_no_filename
196
+ - test/multipart/empty
197
+ - test/multipart/fail_16384_nofile
198
+ - test/multipart/file1.txt
199
+ - test/multipart/filename_and_modification_param
200
+ - test/multipart/filename_and_no_name
201
+ - test/multipart/filename_with_escaped_quotes
202
+ - test/multipart/filename_with_escaped_quotes_and_modification_param
203
+ - test/multipart/filename_with_percent_escaped_quotes
204
+ - test/multipart/filename_with_unescaped_percentages
205
+ - test/multipart/filename_with_unescaped_percentages2
206
+ - test/multipart/filename_with_unescaped_percentages3
207
+ - test/multipart/filename_with_unescaped_quotes
208
+ - test/multipart/ie
209
+ - test/multipart/invalid_character
210
+ - test/multipart/mixed_files
211
+ - test/multipart/nested
212
+ - test/multipart/none
213
+ - test/multipart/semicolon
214
+ - test/multipart/text
215
+ - test/multipart/webkit
216
+ - test/rackup/config.ru
217
+ - test/registering_handler/rack/handler/registering_myself.rb
218
+ - test/spec_body_proxy.rb
219
+ - test/spec_builder.rb
220
+ - test/spec_chunked.rb
221
+ - test/spec_file.rb
222
+ - test/spec_handler.rb
223
+ - test/spec_head.rb
224
+ - test/spec_lint.rb
225
+ - test/spec_mime.rb
226
+ - test/spec_mock.rb
227
+ - test/spec_multipart.rb
228
+ - test/spec_recursive.rb
229
+ - test/spec_request.rb
230
+ - test/spec_response.rb
231
+ - test/spec_rewindable_input.rb
232
+ - test/spec_sendfile.rb
233
+ - test/spec_server.rb
234
+ - test/spec_utils.rb
235
+ - test/spec_webrick.rb
236
+ - test/testrequest.rb
237
+ - test/unregistered_handler/rack/handler/unregistered.rb
238
+ - test/unregistered_handler/rack/handler/unregistered_long_one.rb
239
+ - spec/spec_helper.rb
240
+ has_rdoc: