Permalink
Browse files

Merge remote-tracking branch 'upstream/master'

Conflicts:
	test/spec_deflater.rb
  • Loading branch information...
2 parents f48a75a + 0cba6a4 commit 8ac05587d382ce46009b1c0eed0198bdadf3342c @jakubpawlowicz committed Jan 22, 2013
Showing with 916 additions and 191 deletions.
  1. +4 −0 .travis.yml
  2. +9 −0 KNOWN-ISSUES
  3. +102 −4 README.rdoc
  4. +1 −1 Rakefile
  5. +69 −4 SPEC
  6. +1 −1 example/protectedlobster.rb
  7. +2 −2 lib/rack.rb
  8. +1 −1 lib/rack/auth/abstract/request.rb
  9. +1 −1 lib/rack/auth/basic.rb
  10. +1 −1 lib/rack/auth/digest/request.rb
  11. +6 −2 lib/rack/builder.rb
  12. +13 −2 lib/rack/cascade.rb
  13. +5 −0 lib/rack/config.rb
  14. +9 −10 lib/rack/file.rb
  15. +18 −5 lib/rack/handler.rb
  16. +1 −0 lib/rack/handler/webrick.rb
  17. +3 −0 lib/rack/head.rb
  18. +133 −7 lib/rack/lint.rb
  19. +3 −3 lib/rack/lobster.rb
  20. +2 −0 lib/rack/lock.rb
  21. +0 −2 lib/rack/methodoverride.rb
  22. +30 −1 lib/rack/mime.rb
  23. +2 −2 lib/rack/multipart.rb
  24. +10 −3 lib/rack/multipart/parser.rb
  25. +18 −24 lib/rack/request.rb
  26. +2 −2 lib/rack/response.rb
  27. +18 −4 lib/rack/sendfile.rb
  28. +21 −11 lib/rack/server.rb
  29. +16 −10 lib/rack/session/abstract/id.rb
  30. +1 −1 lib/rack/session/cookie.rb
  31. +66 −14 lib/rack/utils.rb
  32. +1 −1 rack.gemspec
  33. +7 −0 test/spec_builder.rb
  34. +8 −0 test/spec_cascade.rb
  35. +1 −1 test/spec_cgi.rb
  36. +3 −5 test/spec_chunked.rb
  37. +3 −6 test/spec_content_length.rb
  38. +0 −3 test/spec_deflater.rb
  39. +1 −1 test/spec_fastcgi.rb
  40. +21 −0 test/spec_file.rb
  41. +18 −7 test/spec_head.rb
  42. +6 −6 test/spec_lint.rb
  43. +5 −8 test/spec_lock.rb
  44. +4 −1 test/spec_methodoverride.rb
  45. +51 −0 test/spec_mime.rb
  46. +1 −1 test/spec_mongrel.rb
  47. +75 −0 test/spec_multipart.rb
  48. +3 −6 test/spec_nulllogger.rb
  49. +10 −3 test/spec_request.rb
  50. +34 −10 test/spec_response.rb
  51. +53 −12 test/spec_sendfile.rb
  52. +7 −1 test/spec_server.rb
  53. +35 −0 test/spec_utils.rb
  54. +1 −1 test/spec_webrick.rb
View
@@ -8,6 +8,7 @@ rvm:
- 1.8.7
- 1.9.2
- 1.9.3
+ - 2.0.0
- rbx
- jruby
- ree
@@ -17,3 +18,6 @@ branches:
notifications:
email: false
irc: "irc.freenode.org#rack"
+matrix:
+ allow_failures:
+ - rvm: 2.0.0
View
@@ -1,3 +1,12 @@
+= Known issues with Rack and ECMA-262
+
+* Many users expect the escape() function defined in ECMA-262 to be compatible
+ with URI. Confusion is especially strong because the documentation for the
+ escape function includes a reference to the URI specifications. ECMA-262
+ escape is not however a URI escape function, it is a javascript escape
+ function, and is not fully compatible. Most notably, for characters outside of
+ the BMP. Users should use the more correct encodeURI functions.
+
= Known issues with Rack and Web servers
* Lighttpd sets wrong SCRIPT_NAME and PATH_INFO if you mount your
View
@@ -29,8 +29,10 @@ These web servers include Rack handlers in their distributions:
* Phusion Passenger (which is mod_rack for Apache and for nginx)
* Puma
* Rainbows!
+* Reel
* Unicorn
* unixrack
+* uWSGI
* Zbatery
Any valid Rack app will run the same on all these handlers, without
@@ -41,6 +43,7 @@ changing anything.
These frameworks include Rack adapters in their distributions:
* Camping
* Coset
+* Espresso
* Halcyon
* Mack
* Maveric
@@ -56,9 +59,6 @@ These frameworks include Rack adapters in their distributions:
* Wee
* ... and many others.
-Current links to these projects can be found at
-http://wiki.ramaze.net/Home#other-frameworks
-
== Available middleware
Between the server and the framework, Rack can be customized to your
@@ -361,7 +361,7 @@ run on port 11211) and memcache-client installed.
* July 16, 2011: Sixteenth public release 1.3.2
* Fix for Rails and rack-test, Rack::Utils#escape calls to_s
-* Not Yet Released: Seventeenth public release 1.3.3
+* September 16, 2011: Seventeenth public release 1.3.3
* Fix bug with broken query parameters in Rack::ShowExceptions
* Rack::Request#cookies no longer swallows exceptions on broken input
* Prevents XSS attacks enabled by bug in Ruby 1.8's regexp engine
@@ -379,6 +379,10 @@ run on port 11211) and memcache-client installed.
* October 17, 2011: Twentieth public release 1.3.5
* Fix annoying warnings caused by the backport in 1.3.4
+* December 28th, 2011: Twenty first public release: 1.1.3.
+ * Security fix. http://www.ocert.org/advisories/ocert-2011-003.html
+ Further information here: http://jruby.org/2011/12/27/jruby-1-6-5-1
+
* December 28th, 2011: Twenty fourth public release 1.4.0
* Ruby 1.8.6 support has officially been dropped. Not all tests pass.
* Raise sane error messages for broken config.ru
@@ -414,11 +418,105 @@ run on port 11211) and memcache-client installed.
* Rack::Static no longer defaults to serving index files
* Rack.release was fixed
+* January 6th, 2013: Twenty sixth public release 1.1.4
+ * Add warnings when users do not provide a session secret
+
+* January 6th, 2013: Twenty seventh public release 1.2.6
+ * Add warnings when users do not provide a session secret
+ * Fix parsing performance for unquoted filenames
+
+* January 6th, 2013: Twenty eighth public release 1.3.7
+ * Add warnings when users do not provide a session secret
+ * Fix parsing performance for unquoted filenames
+ * Updated URI backports
+ * Fix URI backport version matching, and silence constant warnings
+ * Correct parameter parsing with empty values
+ * Correct rackup '-I' flag, to allow multiple uses
+ * Correct rackup pidfile handling
+ * Report rackup line numbers correctly
+ * Fix request loops caused by non-stale nonces with time limits
+ * Fix reloader on Windows
+ * Prevent infinite recursions from Response#to_ary
+ * Various middleware better conforms to the body close specification
+ * Updated language for the body close specification
+ * Additional notes regarding ECMA escape compatibility issues
+ * Fix the parsing of multiple ranges in range headers
+
+* January 6th, 2013: Twenty ninth public release 1.4.2
+ * Add warnings when users do not provide a session secret
+ * Fix parsing performance for unquoted filenames
+ * Updated URI backports
+ * Fix URI backport version matching, and silence constant warnings
+ * Correct parameter parsing with empty values
+ * Correct rackup '-I' flag, to allow multiple uses
+ * Correct rackup pidfile handling
+ * Report rackup line numbers correctly
+ * Fix request loops caused by non-stale nonces with time limits
+ * Fix reloader on Windows
+ * Prevent infinite recursions from Response#to_ary
+ * Various middleware better conforms to the body close specification
+ * Updated language for the body close specification
+ * Additional notes regarding ECMA escape compatibility issues
+ * Fix the parsing of multiple ranges in range headers
+ * Prevent errors from empty parameter keys
+ * Added PATCH verb to Rack::Request
+ * Various documentation updates
+ * Fix session merge semantics (fixes rack-test)
+ * Rack::Static :index can now handle multiple directories
+ * All tests now utilize Rack::Lint (special thanks to Lars Gierth)
+ * Rack::File cache_control parameter is now deprecated, and removed by 1.5
+ * Correct Rack::Directory script name escaping
+ * Rack::Static supports header rules for sophisticated configurations
+ * Multipart parsing now works without a Content-Length header
+ * New logos courtesy of Zachary Scott!
+ * Rack::BodyProxy now explicitly defines #each, useful for C extensions
+ * Cookies that are not URI escaped no longer cause exceptions
+
+* January 7th, 2013: Thirtieth public release 1.3.8
+ * Security: Prevent unbounded reads in large multipart boundaries
+
+* January 7th, 2013: Thirty first public release 1.4.3
+ * Security: Prevent unbounded reads in large multipart boundaries
+
+* January 13th, 2013: Thirty second public release 1.4.4, 1.3.9, 1.2.7, 1.1.5
+ * [SEC] Rack::Auth::AbstractRequest no longer symbolizes arbitrary strings
+ * Fixed erroneous test case in the 1.3.x series
+
+* January 21st, 2013: Thirty third public release 1.5.0
+ * Introduced hijack SPEC, for before-response and after-response hijacking
+ * SessionHash is no longer a Hash subclass
+ * Rack::File cache_control parameter is removed, in place of headers options
+ * Rack::Auth::AbstractRequest#scheme now yields strings, not symbols
+ * Rack::Utils cookie functions now format expires in RFC 2822 format
+ * Rack::File now has a default mime type
+ * rackup -b 'run Rack::File.new(".")', option provides command line configs
+ * Rack::Deflater will no longer double encode bodies
+ * Rack::Mime#match? provides convenience for Accept header matching
+ * Rack::Utils#q_values provides splitting for Accept headers
+ * Rack::Utils#best_q_match provides a helper for Accept headers
+ * Rack::Handler.pick provides convenience for finding available servers
+ * Puma added to the list of default servers (preferred over Webrick)
+ * Various middleware now correctly close body when replacing it
+ * Rack::Request#params is no longer persistent with only GET params
+ * Rack::Request#update_param and #delete_param provide persistent operations
+ * Rack::Request#trusted_proxy? now returns true for local unix sockets
+ * Rack::Response no longer forces Content-Types
+ * Rack::Sendfile provides local mapping configuration options
+ * Rack::Utils#rfc2109 provides old netscape style time output
+ * Updated HTTP status codes
+ * Ruby 1.8.6 likely no longer passes tests, and is no longer fully supported
+
== Contact
Please post bugs, suggestions and patches to
the bug tracker at <http://github.com/rack/rack/issues>.
+Please post security related bugs and suggestions to the core team at
+<https://groups.google.com/group/rack-core> or rack-core@googlegroups.com. This
+list is not public. Due to wide usage of the library, it is strongly preferred
+that we manage timing in order to provide viable patches at the time of
+disclosure. Your assistance in this matter is greatly appreciated.
+
Mailing list archives are available at
<http://groups.google.com/group/rack-devel>.
View
@@ -85,7 +85,7 @@ task :test => 'SPEC' do
specopts = ENV['TESTOPTS'] ||
"-q -t '^(?!Rack::Adapter|Rack::Session::Memcache|Rack::Server|Rack::Handler)'"
- sh "bacon -I./lib:./test #{opts} #{specopts}"
+ sh "bacon -w -I./lib:./test #{opts} #{specopts}"
end
desc "Run all the tests we run on CI"
View
73 SPEC
@@ -60,6 +60,9 @@ Rack-specific variables:
<tt>rack.multithread</tt>:: true if the application object may be simultaneously invoked by another thread in the same process, false otherwise.
<tt>rack.multiprocess</tt>:: true if an equivalent application object may be simultaneously invoked by another process, false otherwise.
<tt>rack.run_once</tt>:: true if the server expects (but does not guarantee!) that the application will only be invoked this one time during the life of its containing process. Normally, this will only be true for a server based on CGI (or something similar).
+<tt>rack.hijack?</tt>:: present and true if the server supports connection hijacking. See below, hijacking.
+<tt>rack.hijack</tt>:: an object responding to #call that must be called at least once before using rack.hijack_io. It is recommended #call return rack.hijack_io as well as setting it in env if necessary.
+<tt>rack.hijack_io</tt>:: if rack.hijack? is true, and rack.hijack has received #call, this will contain an object resembling an IO. See hijacking.
Additional environment specifications have approved to
standardized middleware APIs. None of these are required to
be implemented by the server.
@@ -90,6 +93,7 @@ There are the following restrictions:
* <tt>rack.url_scheme</tt> must either be +http+ or +https+.
* There must be a valid input stream in <tt>rack.input</tt>.
* There must be a valid error stream in <tt>rack.errors</tt>.
+* There may be a valid hijack stream in <tt>rack.hijack_io</tt>
* The <tt>REQUEST_METHOD</tt> must be a valid token.
* The <tt>SCRIPT_NAME</tt>, if non-empty, must start with <tt>/</tt>
* The <tt>PATH_INFO</tt>, if non-empty, must start with <tt>/</tt>
@@ -129,12 +133,72 @@ The error stream must respond to +puts+, +write+ and +flush+.
* +flush+ must be called without arguments and must be called
in order to make the error appear for sure.
* +close+ must never be called on the error stream.
+=== Hijacking
+==== Request (before status)
+If rack.hijack? is true then rack.hijack must respond to #call.
+rack.hijack must return the io that will also be assigned (or is
+already present, in rack.hijack_io.
+
+rack.hijack_io must respond to:
+<tt>read, write, read_nonblock, write_nonblock, flush, close,
+close_read, close_write, closed?</tt>
+
+The semantics of these IO methods must be a best effort match to
+those of a normal ruby IO or Socket object, using standard
+arguments and raising standard exceptions. Servers are encouraged
+to simply pass on real IO objects, although it is recognized that
+this approach is not directly compatible with SPDY and HTTP 2.0.
+
+IO provided in rack.hijack_io should preference the
+IO::WaitReadable and IO::WaitWritable APIs wherever supported.
+
+There is a deliberate lack of full specification around
+rack.hijack_io, as semantics will change from server to server.
+Users are encouraged to utilize this API with a knowledge of their
+server choice, and servers may extend the functionality of
+hijack_io to provide additional features to users. The purpose of
+rack.hijack is for Rack to "get out of the way", as such, Rack only
+provides the minimum of specification and support.
+
+If rack.hijack? is false, then rack.hijack should not be set.
+
+If rack.hijack? is false, then rack.hijack_io should not be set.
+==== Response (after headers)
+It is also possible to hijack a response after the status and headers
+have been sent.
+In order to do this, an application may set the special header
+<tt>rack.hijack</tt> to an object that responds to <tt>call</tt>
+accepting an argument that conforms to the <tt>rack.hijack_io</tt>
+protocol.
+
+After the headers have been sent, and this hijack callback has been
+called, the application is now responsible for the remaining lifecycle
+of the IO. The application is also responsible for maintaining HTTP
+semantics. Of specific note, in almost all cases in the current SPEC,
+applications will have wanted to specify the header Connection:close in
+HTTP/1.1, and not Connection:keep-alive, as there is no protocol for
+returning hijacked sockets to the web server. For that purpose, use the
+body streaming API instead (progressively yielding strings via each).
+
+Servers must ignore the <tt>body</tt> part of the response tuple when
+the <tt>rack.hijack</tt> response API is in use.
+
+The special response header <tt>rack.hijack</tt> must only be set
+if the request env has <tt>rack.hijack?</tt> <tt>true</tt>.
+==== Conventions
+* Middleware should not use hijack unless it is handling the whole
+ response.
+* Middleware may wrap the IO object for the response pattern.
+* Middleware should not wrap the IO object for the request pattern. The
+ request pattern is intended to provide the hijacker with "raw tcp".
== The Response
=== The Status
This is an HTTP status. When parsed as integer (+to_i+), it must be
greater than or equal to 100.
=== The Headers
The header must respond to +each+, and yield values of key and value.
+Special headers starting "rack." are for communicating with the
+server, and must not be sent back to the client.
The header keys must be Strings.
The header must not contain a +Status+ key,
contain keys with <tt>:</tt> or newlines in their name,
@@ -146,9 +210,8 @@ consisting of lines (for multiple header values, e.g. multiple
<tt>Set-Cookie</tt> values) seperated by "\n".
The lines must not contain characters below 037.
=== The Content-Type
-There must be a <tt>Content-Type</tt>, except when the
-+Status+ is 1xx, 204, 205 or 304, in which case there must be none
-given.
+There must not be a <tt>Content-Type</tt>, when the +Status+ is 1xx,
+204, 205 or 304.
=== The Content-Length
There must not be a <tt>Content-Length</tt> header when the
+Status+ is 1xx, 204, 205 or 304.
@@ -157,7 +220,9 @@ The Body must respond to +each+
and must only yield String values.
The Body itself should not be an instance of String, as this will
break in Ruby 1.9.
-If the Body responds to +close+, it will be called after iteration.
+If the Body responds to +close+, it will be called after iteration. If
+the body is replaced by a middleware after action, the original body
+must be closed first, if it repsonds to close.
If the Body responds to +to_path+, it must return a String
identifying the location of a file whose contents are identical
to that produced by calling +each+; this may be used by the
@@ -11,4 +11,4 @@
pretty_protected_lobster = Rack::ShowStatus.new(Rack::ShowExceptions.new(protected_lobster))
-Rack::Handler::WEBrick.run pretty_protected_lobster, :Port => 9292
+Rack::Server.start :app => pretty_protected_lobster, :Port => 9292
View
@@ -11,7 +11,7 @@
module Rack
# The Rack protocol version number implemented.
- VERSION = [1,1]
+ VERSION = [1,2]
# Return the Rack protocol version as a dotted string.
def self.version
@@ -20,7 +20,7 @@ def self.version
# Return the Rack release as a dotted string.
def self.release
- "1.4"
+ "1.5"
end
autoload :Builder, "rack/builder"
@@ -21,7 +21,7 @@ def parts
end
def scheme
- @scheme ||= parts.first.downcase.to_sym
+ @scheme ||= parts.first.downcase
end
def params
View
@@ -41,7 +41,7 @@ def valid?(auth)
class Request < Auth::AbstractRequest
def basic?
- !parts.first.nil? && :basic == scheme
+ !parts.first.nil? && "basic" == scheme
end
def credentials
@@ -11,7 +11,7 @@ def method
end
def digest?
- :digest == scheme
+ "digest" == scheme
end
def correct_uri?
View
@@ -37,15 +37,19 @@ def self.parse_file(config, opts = Server::Options.new)
options = opts.parse! $1.split(/\s+/)
end
cfgfile.sub!(/^__END__\n.*\Z/m, '')
- app = eval "Rack::Builder.new {\n" + cfgfile + "\n}.to_app",
- TOPLEVEL_BINDING, config, 0
+ app = new_from_string cfgfile, config
else
require config
app = Object.const_get(::File.basename(config, '.rb').capitalize)
end
return app, options
end
+ def self.new_from_string(builder_script, file="(rackup)")
+ eval "Rack::Builder.new {\n" + builder_script + "\n}.to_app",
+ TOPLEVEL_BINDING, file, 0
+ end
+
def initialize(default_app = nil,&block)
@use, @map, @run = [], nil, default_app
instance_eval(&block) if block_given?
Oops, something went wrong.

0 comments on commit 8ac0558

Please sign in to comment.