├── vendor └── gems │ ├── rack-1.1.0 │ ├── RDOX │ ├── bin │ │ └── rackup │ ├── example │ │ ├── lobster.ru │ │ ├── protectedlobster.ru │ │ └── protectedlobster.rb │ ├── lib │ │ ├── rack │ │ │ ├── handler │ │ │ │ ├── evented_mongrel.rb │ │ │ │ ├── swiftiplied_mongrel.rb │ │ │ │ ├── thin.rb │ │ │ │ ├── cgi.rb │ │ │ │ ├── lsws.rb │ │ │ │ ├── scgi.rb │ │ │ │ ├── webrick.rb │ │ │ │ ├── fastcgi.rb │ │ │ │ └── mongrel.rb │ │ │ ├── head.rb │ │ │ ├── config.rb │ │ │ ├── lock.rb │ │ │ ├── nulllogger.rb │ │ │ ├── logger.rb │ │ │ ├── adapter │ │ │ │ └── camping.rb │ │ │ ├── etag.rb │ │ │ ├── content_type.rb │ │ │ ├── runtime.rb │ │ │ ├── auth │ │ │ │ ├── abstract │ │ │ │ │ ├── request.rb │ │ │ │ │ └── handler.rb │ │ │ │ ├── digest │ │ │ │ │ ├── request.rb │ │ │ │ │ ├── params.rb │ │ │ │ │ ├── nonce.rb │ │ │ │ │ └── md5.rb │ │ │ │ └── basic.rb │ │ │ ├── methodoverride.rb │ │ │ ├── content_length.rb │ │ │ ├── cascade.rb │ │ │ ├── static.rb │ │ │ ├── chunked.rb │ │ │ ├── commonlogger.rb │ │ │ ├── conditionalget.rb │ │ │ ├── recursive.rb │ │ │ ├── urlmap.rb │ │ │ ├── lobster.rb │ │ │ ├── builder.rb │ │ │ ├── file.rb │ │ │ ├── handler.rb │ │ │ ├── session │ │ │ │ ├── cookie.rb │ │ │ │ └── pool.rb │ │ │ ├── deflater.rb │ │ │ ├── reloader.rb │ │ │ ├── rewindable_input.rb │ │ │ ├── showstatus.rb │ │ │ ├── response.rb │ │ │ └── directory.rb │ │ └── rack.rb │ ├── test │ │ ├── spec_rack_nulllogger.rb │ │ ├── spec_rack_logger.rb │ │ ├── spec_rack_etag.rb │ │ ├── spec_rack_showexceptions.rb │ │ ├── spec_rack_config.rb │ │ ├── spec_rack_static.rb │ │ ├── spec_rack_head.rb │ │ ├── spec_rack_lock.rb │ │ ├── spec_rack_content_type.rb │ │ ├── spec_rack_conditionalget.rb │ │ ├── spec_rack_camping.rb │ │ ├── spec_rack_lobster.rb │ │ ├── spec_rack_runtime.rb │ │ ├── spec_rack_handler.rb │ │ ├── spec_rack_directory.rb │ │ ├── spec_rack_commonlogger.rb │ │ ├── spec_rack_content_length.rb │ │ ├── spec_rack_cascade.rb │ │ ├── spec_rack_file.rb │ │ ├── spec_rack_methodoverride.rb │ │ ├── spec_rack_auth_basic.rb │ │ ├── spec_rack_recursive.rb │ │ ├── spec_rack_chunked.rb │ │ ├── spec_rack_builder.rb │ │ ├── spec_rack_sendfile.rb │ │ ├── spec_rack_cgi.rb │ │ ├── spec_rack_showstatus.rb │ │ ├── spec_rack_thin.rb │ │ ├── spec_rack_fastcgi.rb │ │ ├── spec_rack_session_cookie.rb │ │ ├── spec_rack_rewindable_input.rb │ │ ├── spec_rackup.rb │ │ └── spec_rack_webrick.rb │ ├── KNOWN-ISSUES │ ├── COPYING │ └── rack.gemspec │ └── sinatra-1.0 │ ├── test │ ├── public │ │ └── favicon.ico │ ├── views │ │ ├── hello.test │ │ ├── layout2.test │ │ ├── hello.erb │ │ ├── hello.erubis │ │ ├── hello.haml │ │ ├── error.sass │ │ ├── foo │ │ │ └── hello.test │ │ ├── layout2.erb │ │ ├── layout2.haml │ │ ├── hello.sass │ │ ├── layout2.erubis │ │ ├── hello.builder │ │ ├── error.builder │ │ ├── layout2.builder │ │ ├── hello.less │ │ ├── error.haml │ │ ├── error.erb │ │ └── error.erubis │ ├── sinatra_test.rb │ ├── less_test.rb │ ├── server_test.rb │ ├── request_test.rb │ ├── response_test.rb │ ├── route_added_hook_test.rb │ ├── builder_test.rb │ ├── contest.rb │ ├── helper.rb │ ├── middleware_test.rb │ ├── erb_test.rb │ ├── erubis_test.rb │ ├── result_test.rb │ ├── haml_test.rb │ ├── sass_test.rb │ ├── static_test.rb │ ├── extensions_test.rb │ └── templates_test.rb │ ├── lib │ ├── sinatra │ │ ├── images │ │ │ ├── 404.png │ │ │ └── 500.png │ │ └── main.rb │ └── sinatra.rb │ ├── LICENSE │ ├── AUTHORS │ ├── sinatra.gemspec │ └── Rakefile ├── README └── spycam.rb /vendor/gems/rack-1.1.0/RDOX: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/hello.test: -------------------------------------------------------------------------------- 1 | Hello World! 2 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/layout2.test: -------------------------------------------------------------------------------- 1 | Layout 2! 2 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/hello.erb: -------------------------------------------------------------------------------- 1 | Hello <%= 'World' %> 2 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/hello.erubis: -------------------------------------------------------------------------------- 1 | Hello <%= 'World' %> 2 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/hello.haml: -------------------------------------------------------------------------------- 1 | %h1 Hello From Haml 2 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/error.sass: -------------------------------------------------------------------------------- 1 | #sass 2 | +argle-bargle 3 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/foo/hello.test: -------------------------------------------------------------------------------- 1 | from another views directory 2 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/layout2.erb: -------------------------------------------------------------------------------- 1 | ERB Layout! 2 | <%= yield %> 3 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/layout2.haml: -------------------------------------------------------------------------------- 1 | %h1 HAML Layout! 2 | %p= yield 3 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/hello.sass: -------------------------------------------------------------------------------- 1 | #sass 2 | :background-color #FFF 3 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/layout2.erubis: -------------------------------------------------------------------------------- 1 | ERubis Layout! 2 | <%= yield %> 3 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/hello.builder: -------------------------------------------------------------------------------- 1 | xml.exclaim "You're my boy, #{@name}!" 2 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/error.builder: -------------------------------------------------------------------------------- 1 | xml.error do 2 | raise "goodbye" 3 | end 4 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/layout2.builder: -------------------------------------------------------------------------------- 1 | xml.layout do 2 | xml << yield 3 | end 4 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/bin/rackup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "rack" 4 | Rack::Server.start 5 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/example/lobster.ru: -------------------------------------------------------------------------------- 1 | require 'rack/lobster' 2 | 3 | use Rack::ShowExceptions 4 | run Rack::Lobster.new 5 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/hello.less: -------------------------------------------------------------------------------- 1 | @white_colour: #fff; 2 | 3 | #main { 4 | background-color: @white_colour; 5 | } -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/lib/sinatra/images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mleone/spycam/HEAD/vendor/gems/sinatra-1.0/lib/sinatra/images/404.png -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/lib/sinatra/images/500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mleone/spycam/HEAD/vendor/gems/sinatra-1.0/lib/sinatra/images/500.png -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/error.haml: -------------------------------------------------------------------------------- 1 | %h1 Hello From Haml 2 | = raise 'goodbye' unless defined?(french) && french 3 | = raise 'au revoir' if defined?(french) && french 4 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/error.erb: -------------------------------------------------------------------------------- 1 | Hello <%= 'World' %> 2 | <% raise 'Goodbye' unless defined?(french) && french %> 3 | <% raise 'Au revoir' if defined?(french) && french %> 4 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/views/error.erubis: -------------------------------------------------------------------------------- 1 | Hello <%= 'World' %> 2 | <% raise 'Goodbye' unless defined?(french) && french %> 3 | <% raise 'Au revoir' if defined?(french) && french %> 4 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/handler/evented_mongrel.rb: -------------------------------------------------------------------------------- 1 | require 'swiftcore/evented_mongrel' 2 | 3 | module Rack 4 | module Handler 5 | class EventedMongrel < Handler::Mongrel 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/handler/swiftiplied_mongrel.rb: -------------------------------------------------------------------------------- 1 | require 'swiftcore/swiftiplied_mongrel' 2 | 3 | module Rack 4 | module Handler 5 | class SwiftipliedMongrel < Handler::Mongrel 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/lib/sinatra.rb: -------------------------------------------------------------------------------- 1 | libdir = File.dirname(__FILE__) 2 | $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir) 3 | 4 | require 'sinatra/base' 5 | require 'sinatra/main' 6 | 7 | enable :inline_templates 8 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/example/protectedlobster.ru: -------------------------------------------------------------------------------- 1 | require 'rack/lobster' 2 | 3 | use Rack::ShowExceptions 4 | use Rack::Auth::Basic, "Lobster 2.0" do |username, password| 5 | 'secret' == password 6 | end 7 | 8 | run Rack::Lobster.new 9 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Simple embedded web application in Ruby for use in Android Devices. 2 | 3 | Featured on my blog at http://leone.panopticdev.com 4 | 5 | For demonstrative and educational purposes. 6 | 7 | This application is built to run on Scripting Layer for Android: 8 | http://code.google.com/p/android-scripting/ 9 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/head.rb: -------------------------------------------------------------------------------- 1 | module Rack 2 | 3 | class Head 4 | def initialize(app) 5 | @app = app 6 | end 7 | 8 | def call(env) 9 | status, headers, body = @app.call(env) 10 | 11 | if env["REQUEST_METHOD"] == "HEAD" 12 | [status, headers, []] 13 | else 14 | [status, headers, body] 15 | end 16 | end 17 | end 18 | 19 | end 20 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/config.rb: -------------------------------------------------------------------------------- 1 | module Rack 2 | # Rack::Config modifies the environment using the block given during 3 | # initialization. 4 | class Config 5 | def initialize(app, &block) 6 | @app = app 7 | @block = block 8 | end 9 | 10 | def call(env) 11 | @block.call(env) 12 | @app.call(env) 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/sinatra_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/helper' 2 | 3 | class SinatraTest < Test::Unit::TestCase 4 | it 'creates a new Sinatra::Base subclass on new' do 5 | app = 6 | Sinatra.new do 7 | get '/' do 8 | 'Hello World' 9 | end 10 | end 11 | assert_same Sinatra::Base, app.superclass 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/lock.rb: -------------------------------------------------------------------------------- 1 | module Rack 2 | class Lock 3 | FLAG = 'rack.multithread'.freeze 4 | 5 | def initialize(app, lock = Mutex.new) 6 | @app, @lock = app, lock 7 | end 8 | 9 | def call(env) 10 | old, env[FLAG] = env[FLAG], false 11 | @lock.synchronize { @app.call(env) } 12 | ensure 13 | env[FLAG] = old 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_nulllogger.rb: -------------------------------------------------------------------------------- 1 | require 'rack/nulllogger' 2 | require 'rack/lint' 3 | require 'rack/mock' 4 | 5 | context "Rack::NullLogger" do 6 | specify "acks as a nop logger" do 7 | app = lambda { |env| 8 | env['rack.logger'].warn "b00m" 9 | [200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] 10 | } 11 | Rack::NullLogger.new(app).call({}) 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/example/protectedlobster.rb: -------------------------------------------------------------------------------- 1 | require 'rack' 2 | require 'rack/lobster' 3 | 4 | lobster = Rack::Lobster.new 5 | 6 | protected_lobster = Rack::Auth::Basic.new(lobster) do |username, password| 7 | 'secret' == password 8 | end 9 | 10 | protected_lobster.realm = 'Lobster 2.0' 11 | 12 | pretty_protected_lobster = Rack::ShowStatus.new(Rack::ShowExceptions.new(protected_lobster)) 13 | 14 | Rack::Handler::WEBrick.run pretty_protected_lobster, :Port => 9292 15 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/nulllogger.rb: -------------------------------------------------------------------------------- 1 | module Rack 2 | class NullLogger 3 | def initialize(app) 4 | @app = app 5 | end 6 | 7 | def call(env) 8 | env['rack.logger'] = self 9 | @app.call(env) 10 | end 11 | 12 | def info(progname = nil, &block); end 13 | def debug(progname = nil, &block); end 14 | def warn(progname = nil, &block); end 15 | def error(progname = nil, &block); end 16 | def fatal(progname = nil, &block); end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/logger.rb: -------------------------------------------------------------------------------- 1 | require 'logger' 2 | 3 | module Rack 4 | # Sets up rack.logger to write to rack.errors stream 5 | class Logger 6 | def initialize(app, level = ::Logger::INFO) 7 | @app, @level = app, level 8 | end 9 | 10 | def call(env) 11 | logger = ::Logger.new(env['rack.errors']) 12 | logger.level = @level 13 | 14 | env['rack.logger'] = logger 15 | @app.call(env) 16 | ensure 17 | logger.close 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/handler/thin.rb: -------------------------------------------------------------------------------- 1 | require "thin" 2 | require "rack/content_length" 3 | require "rack/chunked" 4 | 5 | module Rack 6 | module Handler 7 | class Thin 8 | def self.run(app, options={}) 9 | app = Rack::Chunked.new(Rack::ContentLength.new(app)) 10 | server = ::Thin::Server.new(options[:Host] || '0.0.0.0', 11 | options[:Port] || 8080, 12 | app) 13 | yield server if block_given? 14 | server.start 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/adapter/camping.rb: -------------------------------------------------------------------------------- 1 | module Rack 2 | module Adapter 3 | class Camping 4 | def initialize(app) 5 | @app = app 6 | end 7 | 8 | def call(env) 9 | env["PATH_INFO"] ||= "" 10 | env["SCRIPT_NAME"] ||= "" 11 | controller = @app.run(env['rack.input'], env) 12 | h = controller.headers 13 | h.each_pair do |k,v| 14 | if v.kind_of? URI 15 | h[k] = v.to_s 16 | end 17 | end 18 | [controller.status, controller.headers, [controller.body.to_s]] 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/etag.rb: -------------------------------------------------------------------------------- 1 | require 'digest/md5' 2 | 3 | module Rack 4 | # Automatically sets the ETag header on all String bodies 5 | class ETag 6 | def initialize(app) 7 | @app = app 8 | end 9 | 10 | def call(env) 11 | status, headers, body = @app.call(env) 12 | 13 | if !headers.has_key?('ETag') 14 | parts = [] 15 | body.each { |part| parts << part.to_s } 16 | headers['ETag'] = %("#{Digest::MD5.hexdigest(parts.join(""))}") 17 | [status, headers, parts] 18 | else 19 | [status, headers, body] 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_logger.rb: -------------------------------------------------------------------------------- 1 | require 'rack/logger' 2 | require 'rack/lint' 3 | require 'stringio' 4 | 5 | context "Rack::Logger" do 6 | specify "logs to rack.errors" do 7 | app = lambda { |env| 8 | log = env['rack.logger'] 9 | log.debug("Created logger") 10 | log.info("Program started") 11 | log.warn("Nothing to do!") 12 | 13 | [200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] 14 | } 15 | 16 | errors = StringIO.new 17 | Rack::Logger.new(app).call({'rack.errors' => errors}) 18 | errors.string.should.match "INFO -- : Program started" 19 | errors.string.should.match "WARN -- : Nothing to do" 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/KNOWN-ISSUES: -------------------------------------------------------------------------------- 1 | = Known issues with Rack and Web servers 2 | 3 | * Lighttpd sets wrong SCRIPT_NAME and PATH_INFO if you mount your 4 | FastCGI app at "/". This can be fixed by using this middleware: 5 | 6 | class LighttpdScriptNameFix 7 | def initialize(app) 8 | @app = app 9 | end 10 | 11 | def call(env) 12 | env["PATH_INFO"] = env["SCRIPT_NAME"].to_s + env["PATH_INFO"].to_s 13 | env["SCRIPT_NAME"] = "" 14 | @app.call(env) 15 | end 16 | end 17 | 18 | Of course, use this only when your app runs at "/". 19 | 20 | Since lighttpd 1.4.23, you also can use the "fix-root-scriptname" flag 21 | in fastcgi.server. 22 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_etag.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | require 'rack/mock' 3 | require 'rack/etag' 4 | 5 | context "Rack::ETag" do 6 | specify "sets ETag if none is set" do 7 | app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] } 8 | response = Rack::ETag.new(app).call({}) 9 | response[1]['ETag'].should.equal "\"65a8e27d8879283831b664bd8b7f0ad4\"" 10 | end 11 | 12 | specify "does not change ETag if it is already set" do 13 | app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'ETag' => '"abc"'}, ["Hello, World!"]] } 14 | response = Rack::ETag.new(app).call({}) 15 | response[1]['ETag'].should.equal "\"abc\"" 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_showexceptions.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | 3 | require 'rack/showexceptions' 4 | require 'rack/mock' 5 | 6 | context "Rack::ShowExceptions" do 7 | specify "catches exceptions" do 8 | res = nil 9 | req = Rack::MockRequest.new(Rack::ShowExceptions.new(lambda { |env| 10 | raise RuntimeError 11 | })) 12 | lambda { 13 | res = req.get("/") 14 | }.should.not.raise 15 | res.should.be.a.server_error 16 | res.status.should.equal 500 17 | 18 | res.should =~ /RuntimeError/ 19 | res.should =~ /ShowExceptions/ 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/content_type.rb: -------------------------------------------------------------------------------- 1 | require 'rack/utils' 2 | 3 | module Rack 4 | 5 | # Sets the Content-Type header on responses which don't have one. 6 | # 7 | # Builder Usage: 8 | # use Rack::ContentType, "text/plain" 9 | # 10 | # When no content type argument is provided, "text/html" is assumed. 11 | class ContentType 12 | def initialize(app, content_type = "text/html") 13 | @app, @content_type = app, content_type 14 | end 15 | 16 | def call(env) 17 | status, headers, body = @app.call(env) 18 | headers = Utils::HeaderHash.new(headers) 19 | headers['Content-Type'] ||= @content_type 20 | [status, headers, body] 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_config.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | require 'rack/mock' 3 | require 'rack/builder' 4 | require 'rack/content_length' 5 | require 'rack/config' 6 | 7 | context "Rack::Config" do 8 | 9 | specify "should accept a block that modifies the environment" do 10 | app = Rack::Builder.new do 11 | use Rack::Lint 12 | use Rack::ContentLength 13 | use Rack::Config do |env| 14 | env['greeting'] = 'hello' 15 | end 16 | run lambda { |env| 17 | [200, {'Content-Type' => 'text/plain'}, [env['greeting'] || '']] 18 | } 19 | end 20 | response = Rack::MockRequest.new(app).get('/') 21 | response.body.should.equal('hello') 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/runtime.rb: -------------------------------------------------------------------------------- 1 | module Rack 2 | # Sets an "X-Runtime" response header, indicating the response 3 | # time of the request, in seconds 4 | # 5 | # You can put it right before the application to see the processing 6 | # time, or before all the other middlewares to include time for them, 7 | # too. 8 | class Runtime 9 | def initialize(app, name = nil) 10 | @app = app 11 | @header_name = "X-Runtime" 12 | @header_name << "-#{name}" if name 13 | end 14 | 15 | def call(env) 16 | start_time = Time.now 17 | status, headers, body = @app.call(env) 18 | request_time = Time.now - start_time 19 | 20 | if !headers.has_key?(@header_name) 21 | headers[@header_name] = "%0.6f" % request_time 22 | end 23 | 24 | [status, headers, body] 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/auth/abstract/request.rb: -------------------------------------------------------------------------------- 1 | module Rack 2 | module Auth 3 | class AbstractRequest 4 | 5 | def initialize(env) 6 | @env = env 7 | end 8 | 9 | def provided? 10 | !authorization_key.nil? 11 | end 12 | 13 | def parts 14 | @parts ||= @env[authorization_key].split(' ', 2) 15 | end 16 | 17 | def scheme 18 | @scheme ||= parts.first.downcase.to_sym 19 | end 20 | 21 | def params 22 | @params ||= parts.last 23 | end 24 | 25 | 26 | private 27 | 28 | AUTHORIZATION_KEYS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION'] 29 | 30 | def authorization_key 31 | @authorization_key ||= AUTHORIZATION_KEYS.detect { |key| @env.has_key?(key) } 32 | end 33 | 34 | end 35 | 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/methodoverride.rb: -------------------------------------------------------------------------------- 1 | module Rack 2 | class MethodOverride 3 | HTTP_METHODS = %w(GET HEAD PUT POST DELETE OPTIONS) 4 | 5 | METHOD_OVERRIDE_PARAM_KEY = "_method".freeze 6 | HTTP_METHOD_OVERRIDE_HEADER = "HTTP_X_HTTP_METHOD_OVERRIDE".freeze 7 | 8 | def initialize(app) 9 | @app = app 10 | end 11 | 12 | def call(env) 13 | if env["REQUEST_METHOD"] == "POST" 14 | req = Request.new(env) 15 | method = req.POST[METHOD_OVERRIDE_PARAM_KEY] || 16 | env[HTTP_METHOD_OVERRIDE_HEADER] 17 | method = method.to_s.upcase 18 | if HTTP_METHODS.include?(method) 19 | env["rack.methodoverride.original_method"] = env["REQUEST_METHOD"] 20 | env["REQUEST_METHOD"] = method 21 | end 22 | end 23 | 24 | @app.call(env) 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/content_length.rb: -------------------------------------------------------------------------------- 1 | require 'rack/utils' 2 | 3 | module Rack 4 | # Sets the Content-Length header on responses with fixed-length bodies. 5 | class ContentLength 6 | include Rack::Utils 7 | 8 | def initialize(app) 9 | @app = app 10 | end 11 | 12 | def call(env) 13 | status, headers, body = @app.call(env) 14 | headers = HeaderHash.new(headers) 15 | 16 | if !STATUS_WITH_NO_ENTITY_BODY.include?(status) && 17 | !headers['Content-Length'] && 18 | !headers['Transfer-Encoding'] && 19 | (body.respond_to?(:to_ary) || body.respond_to?(:to_str)) 20 | 21 | body = [body] if body.respond_to?(:to_str) # rack 0.4 compat 22 | length = body.to_ary.inject(0) { |len, part| len + bytesize(part) } 23 | headers['Content-Length'] = length.to_s 24 | end 25 | 26 | [status, headers, body] 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/lib/sinatra/main.rb: -------------------------------------------------------------------------------- 1 | require 'sinatra/base' 2 | 3 | module Sinatra 4 | class Application < Base 5 | 6 | # we assume that the first file that requires 'sinatra' is the 7 | # app_file. all other path related options are calculated based 8 | # on this path by default. 9 | set :app_file, caller_files.first || $0 10 | 11 | set :run, Proc.new { $0 == app_file } 12 | 13 | if run? && ARGV.any? 14 | require 'optparse' 15 | OptionParser.new { |op| 16 | op.on('-x') { set :lock, true } 17 | op.on('-e env') { |val| set :environment, val.to_sym } 18 | op.on('-s server') { |val| set :server, val } 19 | op.on('-p port') { |val| set :port, val.to_i } 20 | op.on('-o addr') { |val| set :bind, val } 21 | }.parse!(ARGV.dup) 22 | end 23 | end 24 | 25 | at_exit { Application.run! if $!.nil? && Application.run? } 26 | end 27 | 28 | include Sinatra::Delegator 29 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/cascade.rb: -------------------------------------------------------------------------------- 1 | module Rack 2 | # Rack::Cascade tries an request on several apps, and returns the 3 | # first response that is not 404 (or in a list of configurable 4 | # status codes). 5 | 6 | class Cascade 7 | NotFound = [404, {}, []] 8 | 9 | attr_reader :apps 10 | 11 | def initialize(apps, catch=404) 12 | @apps = []; @has_app = {} 13 | apps.each { |app| add app } 14 | 15 | @catch = {} 16 | [*catch].each { |status| @catch[status] = true } 17 | end 18 | 19 | def call(env) 20 | result = NotFound 21 | 22 | @apps.each do |app| 23 | result = app.call(env) 24 | break unless @catch.include?(result[0].to_i) 25 | end 26 | 27 | result 28 | end 29 | 30 | def add app 31 | @has_app[app] = true 32 | @apps << app 33 | end 34 | 35 | def include? app 36 | @has_app.include? app 37 | end 38 | 39 | alias_method :<<, :add 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_static.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | 3 | require 'rack/static' 4 | require 'rack/mock' 5 | 6 | class DummyApp 7 | def call(env) 8 | [200, {}, ["Hello World"]] 9 | end 10 | end 11 | 12 | context "Rack::Static" do 13 | root = File.expand_path(File.dirname(__FILE__)) 14 | OPTIONS = {:urls => ["/cgi"], :root => root} 15 | 16 | setup do 17 | @request = Rack::MockRequest.new(Rack::Static.new(DummyApp.new, OPTIONS)) 18 | end 19 | 20 | specify "serves files" do 21 | res = @request.get("/cgi/test") 22 | res.should.be.ok 23 | res.body.should =~ /ruby/ 24 | end 25 | 26 | specify "404s if url root is known but it can't find the file" do 27 | res = @request.get("/cgi/foo") 28 | res.should.be.not_found 29 | end 30 | 31 | specify "calls down the chain if url root is not known" do 32 | res = @request.get("/something/else") 33 | res.should.be.ok 34 | res.body.should == "Hello World" 35 | end 36 | 37 | end 38 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/auth/abstract/handler.rb: -------------------------------------------------------------------------------- 1 | module Rack 2 | module Auth 3 | # Rack::Auth::AbstractHandler implements common authentication functionality. 4 | # 5 | # +realm+ should be set for all handlers. 6 | 7 | class AbstractHandler 8 | 9 | attr_accessor :realm 10 | 11 | def initialize(app, realm=nil, &authenticator) 12 | @app, @realm, @authenticator = app, realm, authenticator 13 | end 14 | 15 | 16 | private 17 | 18 | def unauthorized(www_authenticate = challenge) 19 | return [ 401, 20 | { 'Content-Type' => 'text/plain', 21 | 'Content-Length' => '0', 22 | 'WWW-Authenticate' => www_authenticate.to_s }, 23 | [] 24 | ] 25 | end 26 | 27 | def bad_request 28 | return [ 400, 29 | { 'Content-Type' => 'text/plain', 30 | 'Content-Length' => '0' }, 31 | [] 32 | ] 33 | end 34 | 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/auth/digest/request.rb: -------------------------------------------------------------------------------- 1 | require 'rack/auth/abstract/request' 2 | require 'rack/auth/digest/params' 3 | require 'rack/auth/digest/nonce' 4 | 5 | module Rack 6 | module Auth 7 | module Digest 8 | class Request < Auth::AbstractRequest 9 | 10 | def method 11 | @env['rack.methodoverride.original_method'] || @env['REQUEST_METHOD'] 12 | end 13 | 14 | def digest? 15 | :digest == scheme 16 | end 17 | 18 | def correct_uri? 19 | (@env['SCRIPT_NAME'].to_s + @env['PATH_INFO'].to_s) == uri 20 | end 21 | 22 | def nonce 23 | @nonce ||= Nonce.parse(params['nonce']) 24 | end 25 | 26 | def params 27 | @params ||= Params.parse(parts.last) 28 | end 29 | 30 | def method_missing(sym) 31 | if params.has_key? key = sym.to_s 32 | return params[key] 33 | end 34 | super 35 | end 36 | 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /spycam.rb: -------------------------------------------------------------------------------- 1 | APP_DIR = File.expand_path File.dirname(__FILE__) 2 | GEM_DIR = File.join(APP_DIR, 'vendor', 'gems') 3 | PUBLIC_DIR = File.join(APP_DIR, 'public') 4 | 5 | # Vendorize all gems in vendor directory. 6 | Dir.entries(GEM_DIR).each do |dir| 7 | gem_lib = File.join GEM_DIR, dir, 'lib' 8 | $LOAD_PATH << gem_lib if File.exist?(gem_lib) 9 | end 10 | 11 | require "rack" 12 | require "sinatra/base" 13 | 14 | require "android" 15 | 16 | DROID = Android.new 17 | 18 | TEMPLATE = < 20 | 21 | 22 | 23 | Android Camera 24 | 25 | 26 | 27 | 28 | 29 | HTML 30 | 31 | class SpyCam < Sinatra::Base 32 | set :public, File.join(APP_DIR, 'public') 33 | 34 | get "/" do 35 | snapshot_path = File.join PUBLIC_DIR, 'latest.png' 36 | DROID.cameraCapturePicture snapshot_path 37 | TEMPLATE 38 | end 39 | end 40 | 41 | SpyCam.run! 42 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_head.rb: -------------------------------------------------------------------------------- 1 | require 'rack/head' 2 | require 'rack/mock' 3 | 4 | context "Rack::Head" do 5 | def test_response(headers = {}) 6 | app = lambda { |env| [200, {"Content-type" => "test/plain", "Content-length" => "3"}, ["foo"]] } 7 | request = Rack::MockRequest.env_for("/", headers) 8 | response = Rack::Head.new(app).call(request) 9 | 10 | return response 11 | end 12 | 13 | specify "passes GET, POST, PUT, DELETE, OPTIONS, TRACE requests" do 14 | %w[GET POST PUT DELETE OPTIONS TRACE].each do |type| 15 | resp = test_response("REQUEST_METHOD" => type) 16 | 17 | resp[0].should.equal(200) 18 | resp[1].should.equal({"Content-type" => "test/plain", "Content-length" => "3"}) 19 | resp[2].should.equal(["foo"]) 20 | end 21 | end 22 | 23 | specify "removes body from HEAD requests" do 24 | resp = test_response("REQUEST_METHOD" => "HEAD") 25 | 26 | resp[0].should.equal(200) 27 | resp[1].should.equal({"Content-type" => "test/plain", "Content-length" => "3"}) 28 | resp[2].should.equal([]) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_lock.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | 3 | require 'rack/mock' 4 | require 'rack/lock' 5 | 6 | context "Rack::Lock" do 7 | class Lock 8 | attr_reader :synchronized 9 | 10 | def initialize 11 | @synchronized = false 12 | end 13 | 14 | def synchronize 15 | @synchronized = true 16 | yield 17 | end 18 | end 19 | 20 | specify "should call synchronize on lock" do 21 | lock = Lock.new 22 | env = Rack::MockRequest.env_for("/") 23 | app = Rack::Lock.new(lambda { |env| }, lock) 24 | lock.synchronized.should.equal false 25 | app.call(env) 26 | lock.synchronized.should.equal true 27 | end 28 | 29 | specify "should set multithread flag to false" do 30 | app = Rack::Lock.new(lambda { |env| env['rack.multithread'] }) 31 | app.call(Rack::MockRequest.env_for("/")).should.equal false 32 | end 33 | 34 | specify "should reset original multithread flag when exiting lock" do 35 | app = Rack::Lock.new(lambda { |env| env }) 36 | app.call(Rack::MockRequest.env_for("/"))['rack.multithread'].should.equal true 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/less_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/helper' 2 | require 'less' 3 | 4 | class LessTest < Test::Unit::TestCase 5 | def less_app(&block) 6 | mock_app { 7 | set :views, File.dirname(__FILE__) + '/views' 8 | get '/', &block 9 | } 10 | get '/' 11 | end 12 | 13 | it 'renders inline Less strings' do 14 | less_app { less "@white_color: #fff; #main { background-color: @white_color }"} 15 | assert ok? 16 | assert_equal "#main { background-color: #ffffff; }\n", body 17 | end 18 | 19 | it 'renders .less files in views path' do 20 | less_app { less :hello } 21 | assert ok? 22 | assert_equal "#main { background-color: #ffffff; }\n", body 23 | end 24 | 25 | it 'ignores the layout option' do 26 | less_app { less :hello, :layout => :layout2 } 27 | assert ok? 28 | assert_equal "#main { background-color: #ffffff; }\n", body 29 | end 30 | 31 | it "raises error if template not found" do 32 | mock_app { 33 | get('/') { less :no_such_template } 34 | } 35 | assert_raise(Errno::ENOENT) { get('/') } 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/server_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/helper' 2 | 3 | module Rack::Handler 4 | class Mock 5 | extend Test::Unit::Assertions 6 | 7 | def self.run(app, options={}) 8 | assert(app < Sinatra::Base) 9 | assert_equal 9001, options[:Port] 10 | assert_equal 'foo.local', options[:Host] 11 | yield new 12 | end 13 | 14 | def stop 15 | end 16 | end 17 | 18 | register 'mock', 'Rack::Handler::Mock' 19 | end 20 | 21 | class ServerTest < Test::Unit::TestCase 22 | setup do 23 | mock_app { 24 | set :server, 'mock' 25 | set :bind, 'foo.local' 26 | set :port, 9001 27 | } 28 | $stdout = File.open('/dev/null', 'wb') 29 | end 30 | 31 | def teardown 32 | $stdout = STDOUT 33 | end 34 | 35 | it "locates the appropriate Rack handler and calls ::run" do 36 | @app.run! 37 | end 38 | 39 | it "sets options on the app before running" do 40 | @app.run! :sessions => true 41 | assert @app.sessions? 42 | end 43 | 44 | it "falls back on the next server handler when not found" do 45 | @app.run! :server => %w[foo bar mock] 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007, 2008, 2009 Blake Mizerany 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007, 2008, 2009, 2010 Christian Neukirchen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to 5 | deal in the Software without restriction, including without limitation the 6 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | sell copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/request_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/helper' 2 | 3 | class RequestTest < Test::Unit::TestCase 4 | it 'responds to #user_agent' do 5 | request = Sinatra::Request.new({'HTTP_USER_AGENT' => 'Test'}) 6 | assert request.respond_to?(:user_agent) 7 | assert_equal 'Test', request.user_agent 8 | end 9 | 10 | it 'parses POST params when Content-Type is form-dataish' do 11 | request = Sinatra::Request.new( 12 | 'REQUEST_METHOD' => 'PUT', 13 | 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', 14 | 'rack.input' => StringIO.new('foo=bar') 15 | ) 16 | assert_equal 'bar', request.params['foo'] 17 | end 18 | 19 | it 'is secure when the url scheme is https' do 20 | request = Sinatra::Request.new('rack.url_scheme' => 'https') 21 | assert request.secure? 22 | end 23 | 24 | it 'is not secure when the url scheme is http' do 25 | request = Sinatra::Request.new('rack.url_scheme' => 'http') 26 | assert !request.secure? 27 | end 28 | 29 | it 'respects X-Forwarded-Proto header for proxied SSL' do 30 | request = Sinatra::Request.new('HTTP_X_FORWARDED_PROTO' => 'https') 31 | assert request.secure? 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/static.rb: -------------------------------------------------------------------------------- 1 | module Rack 2 | 3 | # The Rack::Static middleware intercepts requests for static files 4 | # (javascript files, images, stylesheets, etc) based on the url prefixes 5 | # passed in the options, and serves them using a Rack::File object. This 6 | # allows a Rack stack to serve both static and dynamic content. 7 | # 8 | # Examples: 9 | # use Rack::Static, :urls => ["/media"] 10 | # will serve all requests beginning with /media from the "media" folder 11 | # located in the current directory (ie media/*). 12 | # 13 | # use Rack::Static, :urls => ["/css", "/images"], :root => "public" 14 | # will serve all requests beginning with /css or /images from the folder 15 | # "public" in the current directory (ie public/css/* and public/images/*) 16 | 17 | class Static 18 | 19 | def initialize(app, options={}) 20 | @app = app 21 | @urls = options[:urls] || ["/favicon.ico"] 22 | root = options[:root] || Dir.pwd 23 | @file_server = Rack::File.new(root) 24 | end 25 | 26 | def call(env) 27 | path = env["PATH_INFO"] 28 | can_serve = @urls.any? { |url| path.index(url) == 0 } 29 | 30 | if can_serve 31 | @file_server.call(env) 32 | else 33 | @app.call(env) 34 | end 35 | end 36 | 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_content_type.rb: -------------------------------------------------------------------------------- 1 | require 'rack/mock' 2 | require 'rack/content_type' 3 | 4 | context "Rack::ContentType" do 5 | specify "sets Content-Type to default text/html if none is set" do 6 | app = lambda { |env| [200, {}, "Hello, World!"] } 7 | status, headers, body = Rack::ContentType.new(app).call({}) 8 | headers['Content-Type'].should.equal 'text/html' 9 | end 10 | 11 | specify "sets Content-Type to chosen default if none is set" do 12 | app = lambda { |env| [200, {}, "Hello, World!"] } 13 | status, headers, body = 14 | Rack::ContentType.new(app, 'application/octet-stream').call({}) 15 | headers['Content-Type'].should.equal 'application/octet-stream' 16 | end 17 | 18 | specify "does not change Content-Type if it is already set" do 19 | app = lambda { |env| [200, {'Content-Type' => 'foo/bar'}, "Hello, World!"] } 20 | status, headers, body = Rack::ContentType.new(app).call({}) 21 | headers['Content-Type'].should.equal 'foo/bar' 22 | end 23 | 24 | specify "case insensitive detection of Content-Type" do 25 | app = lambda { |env| [200, {'CONTENT-Type' => 'foo/bar'}, "Hello, World!"] } 26 | status, headers, body = Rack::ContentType.new(app).call({}) 27 | headers.to_a.select { |k,v| k.downcase == "content-type" }. 28 | should.equal [["CONTENT-Type","foo/bar"]] 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/chunked.rb: -------------------------------------------------------------------------------- 1 | require 'rack/utils' 2 | 3 | module Rack 4 | 5 | # Middleware that applies chunked transfer encoding to response bodies 6 | # when the response does not include a Content-Length header. 7 | class Chunked 8 | include Rack::Utils 9 | 10 | def initialize(app) 11 | @app = app 12 | end 13 | 14 | def call(env) 15 | status, headers, body = @app.call(env) 16 | headers = HeaderHash.new(headers) 17 | 18 | if env['HTTP_VERSION'] == 'HTTP/1.0' || 19 | STATUS_WITH_NO_ENTITY_BODY.include?(status) || 20 | headers['Content-Length'] || 21 | headers['Transfer-Encoding'] 22 | [status, headers, body] 23 | else 24 | dup.chunk(status, headers, body) 25 | end 26 | end 27 | 28 | def chunk(status, headers, body) 29 | @body = body 30 | headers.delete('Content-Length') 31 | headers['Transfer-Encoding'] = 'chunked' 32 | [status, headers, self] 33 | end 34 | 35 | def each 36 | term = "\r\n" 37 | @body.each do |chunk| 38 | size = bytesize(chunk) 39 | next if size == 0 40 | yield [size.to_s(16), term, chunk, term].join 41 | end 42 | yield ["0", term, "", term].join 43 | end 44 | 45 | def close 46 | @body.close if @body.respond_to?(:close) 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_conditionalget.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | require 'time' 3 | 4 | require 'rack/mock' 5 | require 'rack/conditionalget' 6 | 7 | context "Rack::ConditionalGet" do 8 | specify "should set a 304 status and truncate body when If-Modified-Since hits" do 9 | timestamp = Time.now.httpdate 10 | app = Rack::ConditionalGet.new(lambda { |env| 11 | [200, {'Last-Modified'=>timestamp}, ['TEST']] }) 12 | 13 | response = Rack::MockRequest.new(app). 14 | get("/", 'HTTP_IF_MODIFIED_SINCE' => timestamp) 15 | 16 | response.status.should.equal 304 17 | response.body.should.be.empty 18 | end 19 | 20 | specify "should set a 304 status and truncate body when If-None-Match hits" do 21 | app = Rack::ConditionalGet.new(lambda { |env| 22 | [200, {'Etag'=>'1234'}, ['TEST']] }) 23 | 24 | response = Rack::MockRequest.new(app). 25 | get("/", 'HTTP_IF_NONE_MATCH' => '1234') 26 | 27 | response.status.should.equal 304 28 | response.body.should.be.empty 29 | end 30 | 31 | specify "should not affect non-GET/HEAD requests" do 32 | app = Rack::ConditionalGet.new(lambda { |env| 33 | [200, {'Etag'=>'1234'}, ['TEST']] }) 34 | 35 | response = Rack::MockRequest.new(app). 36 | post("/", 'HTTP_IF_NONE_MATCH' => '1234') 37 | 38 | response.status.should.equal 200 39 | response.body.should.equal 'TEST' 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/auth/digest/params.rb: -------------------------------------------------------------------------------- 1 | module Rack 2 | module Auth 3 | module Digest 4 | class Params < Hash 5 | 6 | def self.parse(str) 7 | split_header_value(str).inject(new) do |header, param| 8 | k, v = param.split('=', 2) 9 | header[k] = dequote(v) 10 | header 11 | end 12 | end 13 | 14 | def self.dequote(str) # From WEBrick::HTTPUtils 15 | ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup 16 | ret.gsub!(/\\(.)/, "\\1") 17 | ret 18 | end 19 | 20 | def self.split_header_value(str) 21 | str.scan( /(\w+\=(?:"[^\"]+"|[^,]+))/n ).collect{ |v| v[0] } 22 | end 23 | 24 | def initialize 25 | super 26 | 27 | yield self if block_given? 28 | end 29 | 30 | def [](k) 31 | super k.to_s 32 | end 33 | 34 | def []=(k, v) 35 | super k.to_s, v.to_s 36 | end 37 | 38 | UNQUOTED = ['qop', 'nc', 'stale'] 39 | 40 | def to_s 41 | inject([]) do |parts, (k, v)| 42 | parts << "#{k}=" + (UNQUOTED.include?(k) ? v.to_s : quote(v)) 43 | parts 44 | end.join(', ') 45 | end 46 | 47 | def quote(str) # From WEBrick::HTTPUtils 48 | '"' << str.gsub(/[\\\"]/o, "\\\1") << '"' 49 | end 50 | 51 | end 52 | end 53 | end 54 | end 55 | 56 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_camping.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | require 'stringio' 3 | require 'uri' 4 | 5 | begin 6 | require 'rack/mock' 7 | 8 | $-w, w = nil, $-w # yuck 9 | require 'camping' 10 | require 'rack/adapter/camping' 11 | 12 | Camping.goes :CampApp 13 | module CampApp 14 | module Controllers 15 | class HW < R('/') 16 | def get 17 | @headers["X-Served-By"] = URI("http://rack.rubyforge.org") 18 | "Camping works!" 19 | end 20 | 21 | def post 22 | "Data: #{input.foo}" 23 | end 24 | end 25 | end 26 | end 27 | $-w = w 28 | 29 | context "Rack::Adapter::Camping" do 30 | specify "works with GET" do 31 | res = Rack::MockRequest.new(Rack::Adapter::Camping.new(CampApp)). 32 | get("/") 33 | 34 | res.should.be.ok 35 | res["Content-Type"].should.equal "text/html" 36 | res["X-Served-By"].should.equal "http://rack.rubyforge.org" 37 | 38 | res.body.should.equal "Camping works!" 39 | end 40 | 41 | specify "works with POST" do 42 | res = Rack::MockRequest.new(Rack::Adapter::Camping.new(CampApp)). 43 | post("/", :input => "foo=bar") 44 | 45 | res.should.be.ok 46 | res.body.should.equal "Data: bar" 47 | end 48 | end 49 | rescue LoadError 50 | $stderr.puts "Skipping Rack::Adapter::Camping tests (Camping is required). `gem install camping` and try again." 51 | end 52 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_lobster.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | 3 | require 'rack/lobster' 4 | require 'rack/mock' 5 | 6 | context "Rack::Lobster::LambdaLobster" do 7 | specify "should be a single lambda" do 8 | Rack::Lobster::LambdaLobster.should.be.kind_of Proc 9 | end 10 | 11 | specify "should look like a lobster" do 12 | res = Rack::MockRequest.new(Rack::Lobster::LambdaLobster).get("/") 13 | res.should.be.ok 14 | res.body.should.include "(,(,,(,,,(" 15 | res.body.should.include "?flip" 16 | end 17 | 18 | specify "should be flippable" do 19 | res = Rack::MockRequest.new(Rack::Lobster::LambdaLobster).get("/?flip") 20 | res.should.be.ok 21 | res.body.should.include "(,,,(,,(,(" 22 | end 23 | end 24 | 25 | context "Rack::Lobster" do 26 | specify "should look like a lobster" do 27 | res = Rack::MockRequest.new(Rack::Lobster.new).get("/") 28 | res.should.be.ok 29 | res.body.should.include "(,(,,(,,,(" 30 | res.body.should.include "?flip" 31 | res.body.should.include "crash" 32 | end 33 | 34 | specify "should be flippable" do 35 | res = Rack::MockRequest.new(Rack::Lobster.new).get("/?flip=left") 36 | res.should.be.ok 37 | res.body.should.include "(,,,(,,(,(" 38 | end 39 | 40 | specify "should provide crashing for testing purposes" do 41 | lambda { 42 | Rack::MockRequest.new(Rack::Lobster.new).get("/?flip=crash") 43 | }.should.raise 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/response_test.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | require File.dirname(__FILE__) + '/helper' 4 | 5 | class ResponseTest < Test::Unit::TestCase 6 | setup do 7 | @response = Sinatra::Response.new 8 | end 9 | 10 | it "initializes with 200, text/html, and empty body" do 11 | assert_equal 200, @response.status 12 | assert_equal 'text/html', @response['Content-Type'] 13 | assert_equal [], @response.body 14 | end 15 | 16 | it 'uses case insensitive headers' do 17 | @response['content-type'] = 'application/foo' 18 | assert_equal 'application/foo', @response['Content-Type'] 19 | assert_equal 'application/foo', @response['CONTENT-TYPE'] 20 | end 21 | 22 | it 'writes to body' do 23 | @response.body = 'Hello' 24 | @response.write ' World' 25 | assert_equal 'Hello World', @response.body 26 | end 27 | 28 | [204, 304].each do |status_code| 29 | it "removes the Content-Type header and body when response status is #{status_code}" do 30 | @response.status = status_code 31 | @response.body = ['Hello World'] 32 | assert_equal [status_code, {}, []], @response.finish 33 | end 34 | end 35 | 36 | it 'Calculates the Content-Length using the bytesize of the body' do 37 | @response.body = ['Hello', 'World!', '✈'] 38 | status, headers, body = @response.finish 39 | assert_equal '14', headers['Content-Length'] 40 | assert_equal @response.body, body 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/auth/basic.rb: -------------------------------------------------------------------------------- 1 | require 'rack/auth/abstract/handler' 2 | require 'rack/auth/abstract/request' 3 | 4 | module Rack 5 | module Auth 6 | # Rack::Auth::Basic implements HTTP Basic Authentication, as per RFC 2617. 7 | # 8 | # Initialize with the Rack application that you want protecting, 9 | # and a block that checks if a username and password pair are valid. 10 | # 11 | # See also: example/protectedlobster.rb 12 | 13 | class Basic < AbstractHandler 14 | 15 | def call(env) 16 | auth = Basic::Request.new(env) 17 | 18 | return unauthorized unless auth.provided? 19 | 20 | return bad_request unless auth.basic? 21 | 22 | if valid?(auth) 23 | env['REMOTE_USER'] = auth.username 24 | 25 | return @app.call(env) 26 | end 27 | 28 | unauthorized 29 | end 30 | 31 | 32 | private 33 | 34 | def challenge 35 | 'Basic realm="%s"' % realm 36 | end 37 | 38 | def valid?(auth) 39 | @authenticator.call(*auth.credentials) 40 | end 41 | 42 | class Request < Auth::AbstractRequest 43 | def basic? 44 | :basic == scheme 45 | end 46 | 47 | def credentials 48 | @credentials ||= params.unpack("m*").first.split(/:/, 2) 49 | end 50 | 51 | def username 52 | credentials.first 53 | end 54 | end 55 | 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/auth/digest/nonce.rb: -------------------------------------------------------------------------------- 1 | require 'digest/md5' 2 | 3 | module Rack 4 | module Auth 5 | module Digest 6 | # Rack::Auth::Digest::Nonce is the default nonce generator for the 7 | # Rack::Auth::Digest::MD5 authentication handler. 8 | # 9 | # +private_key+ needs to set to a constant string. 10 | # 11 | # +time_limit+ can be optionally set to an integer (number of seconds), 12 | # to limit the validity of the generated nonces. 13 | 14 | class Nonce 15 | 16 | class << self 17 | attr_accessor :private_key, :time_limit 18 | end 19 | 20 | def self.parse(string) 21 | new(*string.unpack("m*").first.split(' ', 2)) 22 | end 23 | 24 | def initialize(timestamp = Time.now, given_digest = nil) 25 | @timestamp, @given_digest = timestamp.to_i, given_digest 26 | end 27 | 28 | def to_s 29 | [([ @timestamp, digest ] * ' ')].pack("m*").strip 30 | end 31 | 32 | def digest 33 | ::Digest::MD5.hexdigest([ @timestamp, self.class.private_key ] * ':') 34 | end 35 | 36 | def valid? 37 | digest == @given_digest 38 | end 39 | 40 | def stale? 41 | !self.class.time_limit.nil? && (@timestamp - Time.now.to_i) < self.class.time_limit 42 | end 43 | 44 | def fresh? 45 | !stale? 46 | end 47 | 48 | end 49 | end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_runtime.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | require 'rack/mock' 3 | require 'rack/runtime' 4 | 5 | context "Rack::Runtime" do 6 | specify "sets X-Runtime is none is set" do 7 | app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] } 8 | response = Rack::Runtime.new(app).call({}) 9 | response[1]['X-Runtime'].should =~ /[\d\.]+/ 10 | end 11 | 12 | specify "does not set the X-Runtime if it is already set" do 13 | app = lambda { |env| [200, {'Content-Type' => 'text/plain', "X-Runtime" => "foobar"}, "Hello, World!"] } 14 | response = Rack::Runtime.new(app).call({}) 15 | response[1]['X-Runtime'].should == "foobar" 16 | end 17 | 18 | specify "should allow a suffix to be set" do 19 | app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] } 20 | response = Rack::Runtime.new(app, "Test").call({}) 21 | response[1]['X-Runtime-Test'].should =~ /[\d\.]+/ 22 | end 23 | 24 | specify "should allow multiple timers to be set" do 25 | app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] } 26 | runtime1 = Rack::Runtime.new(app, "App") 27 | runtime2 = Rack::Runtime.new(runtime1, "All") 28 | response = runtime2.call({}) 29 | 30 | response[1]['X-Runtime-App'].should =~ /[\d\.]+/ 31 | response[1]['X-Runtime-All'].should =~ /[\d\.]+/ 32 | 33 | Float(response[1]['X-Runtime-All']).should > Float(response[1]['X-Runtime-App']) 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/rack.gemspec: -------------------------------------------------------------------------------- 1 | Gem::Specification.new do |s| 2 | s.name = "rack" 3 | s.version = "1.1.0" 4 | s.platform = Gem::Platform::RUBY 5 | s.summary = "a modular Ruby webserver interface" 6 | 7 | s.description = <<-EOF 8 | Rack provides minimal, modular and adaptable interface for developing 9 | web applications in Ruby. By wrapping HTTP requests and responses in 10 | the simplest way possible, it unifies and distills the API for web 11 | servers, web frameworks, and software in between (the so-called 12 | middleware) into a single method call. 13 | 14 | Also see http://rack.rubyforge.org. 15 | EOF 16 | 17 | s.files = Dir['{bin/*,contrib/*,example/*,lib/**/*}'] + 18 | %w(COPYING KNOWN-ISSUES rack.gemspec RDOX README SPEC) 19 | s.bindir = 'bin' 20 | s.executables << 'rackup' 21 | s.require_path = 'lib' 22 | s.has_rdoc = true 23 | s.extra_rdoc_files = ['README', 'SPEC', 'KNOWN-ISSUES'] 24 | s.test_files = Dir['test/{test,spec}_*.rb'] 25 | 26 | s.author = 'Christian Neukirchen' 27 | s.email = 'chneukirchen@gmail.com' 28 | s.homepage = 'http://rack.rubyforge.org' 29 | s.rubyforge_project = 'rack' 30 | 31 | s.add_development_dependency 'test-spec' 32 | 33 | s.add_development_dependency 'camping' 34 | s.add_development_dependency 'fcgi' 35 | s.add_development_dependency 'memcache-client' 36 | s.add_development_dependency 'mongrel' 37 | s.add_development_dependency 'thin' 38 | end 39 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_handler.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | 3 | require 'rack/handler' 4 | 5 | class Rack::Handler::Lobster; end 6 | class RockLobster; end 7 | 8 | context "Rack::Handler" do 9 | specify "has registered default handlers" do 10 | Rack::Handler.get('cgi').should.equal Rack::Handler::CGI 11 | Rack::Handler.get('fastcgi').should.equal Rack::Handler::FastCGI 12 | Rack::Handler.get('mongrel').should.equal Rack::Handler::Mongrel 13 | Rack::Handler.get('webrick').should.equal Rack::Handler::WEBrick 14 | end 15 | 16 | specify "handler that doesn't exist should raise a NameError" do 17 | lambda { 18 | Rack::Handler.get('boom') 19 | }.should.raise(NameError) 20 | end 21 | 22 | specify "should get unregistered, but already required, handler by name" do 23 | Rack::Handler.get('Lobster').should.equal Rack::Handler::Lobster 24 | end 25 | 26 | specify "should register custom handler" do 27 | Rack::Handler.register('rock_lobster', 'RockLobster') 28 | Rack::Handler.get('rock_lobster').should.equal RockLobster 29 | end 30 | 31 | specify "should not need registration for properly coded handlers even if not already required" do 32 | begin 33 | $:.push "test/unregistered_handler" 34 | Rack::Handler.get('Unregistered').should.equal Rack::Handler::Unregistered 35 | lambda { 36 | Rack::Handler.get('UnRegistered') 37 | }.should.raise(NameError) 38 | Rack::Handler.get('UnregisteredLongOne').should.equal Rack::Handler::UnregisteredLongOne 39 | ensure 40 | $:.delete "test/unregistered_handler" 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/route_added_hook_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/helper' 2 | 3 | module RouteAddedTest 4 | @routes, @procs = [], [] 5 | def self.routes ; @routes ; end 6 | def self.procs ; @procs ; end 7 | def self.route_added(verb, path, proc) 8 | @routes << [verb, path] 9 | @procs << proc 10 | end 11 | end 12 | 13 | class RouteAddedHookTest < Test::Unit::TestCase 14 | setup { 15 | RouteAddedTest.routes.clear 16 | RouteAddedTest.procs.clear 17 | } 18 | 19 | it "should be notified of an added route" do 20 | mock_app(Class.new(Sinatra::Base)) { 21 | register RouteAddedTest 22 | get('/') {} 23 | } 24 | 25 | assert_equal [["GET", "/"], ["HEAD", "/"]], 26 | RouteAddedTest.routes 27 | end 28 | 29 | it "should include hooks from superclass" do 30 | a = Class.new(Class.new(Sinatra::Base)) 31 | b = Class.new(a) 32 | 33 | a.register RouteAddedTest 34 | b.class_eval { post("/sub_app_route") {} } 35 | 36 | assert_equal [["POST", "/sub_app_route"]], 37 | RouteAddedTest.routes 38 | end 39 | 40 | it "should only run once per extension" do 41 | mock_app(Class.new(Sinatra::Base)) { 42 | register RouteAddedTest 43 | register RouteAddedTest 44 | get('/') {} 45 | } 46 | 47 | assert_equal [["GET", "/"], ["HEAD", "/"]], 48 | RouteAddedTest.routes 49 | end 50 | 51 | it "should pass route blocks as an argument" do 52 | mock_app(Class.new(Sinatra::Base)) { 53 | register RouteAddedTest 54 | get('/') {} 55 | } 56 | 57 | assert_kind_of Proc, RouteAddedTest.procs.first 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/commonlogger.rb: -------------------------------------------------------------------------------- 1 | module Rack 2 | # Rack::CommonLogger forwards every request to an +app+ given, and 3 | # logs a line in the Apache common log format to the +logger+, or 4 | # rack.errors by default. 5 | class CommonLogger 6 | # Common Log Format: http://httpd.apache.org/docs/1.3/logs.html#common 7 | # lilith.local - - [07/Aug/2006 23:58:02] "GET / HTTP/1.1" 500 - 8 | # %{%s - %s [%s] "%s %s%s %s" %d %s\n} % 9 | FORMAT = %{%s - %s [%s] "%s %s%s %s" %d %s %0.4f\n} 10 | 11 | def initialize(app, logger=nil) 12 | @app = app 13 | @logger = logger 14 | end 15 | 16 | def call(env) 17 | began_at = Time.now 18 | status, header, body = @app.call(env) 19 | header = Utils::HeaderHash.new(header) 20 | log(env, status, header, began_at) 21 | [status, header, body] 22 | end 23 | 24 | private 25 | 26 | def log(env, status, header, began_at) 27 | now = Time.now 28 | length = extract_content_length(header) 29 | 30 | logger = @logger || env['rack.errors'] 31 | logger.write FORMAT % [ 32 | env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-", 33 | env["REMOTE_USER"] || "-", 34 | now.strftime("%d/%b/%Y %H:%M:%S"), 35 | env["REQUEST_METHOD"], 36 | env["PATH_INFO"], 37 | env["QUERY_STRING"].empty? ? "" : "?"+env["QUERY_STRING"], 38 | env["HTTP_VERSION"], 39 | status.to_s[0..3], 40 | length, 41 | now - began_at ] 42 | end 43 | 44 | def extract_content_length(headers) 45 | value = headers['Content-Length'] or return '-' 46 | value.to_s == '0' ? '-' : value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/conditionalget.rb: -------------------------------------------------------------------------------- 1 | require 'rack/utils' 2 | 3 | module Rack 4 | 5 | # Middleware that enables conditional GET using If-None-Match and 6 | # If-Modified-Since. The application should set either or both of the 7 | # Last-Modified or Etag response headers according to RFC 2616. When 8 | # either of the conditions is met, the response body is set to be zero 9 | # length and the response status is set to 304 Not Modified. 10 | # 11 | # Applications that defer response body generation until the body's each 12 | # message is received will avoid response body generation completely when 13 | # a conditional GET matches. 14 | # 15 | # Adapted from Michael Klishin's Merb implementation: 16 | # http://github.com/wycats/merb-core/tree/master/lib/merb-core/rack/middleware/conditional_get.rb 17 | class ConditionalGet 18 | def initialize(app) 19 | @app = app 20 | end 21 | 22 | def call(env) 23 | return @app.call(env) unless %w[GET HEAD].include?(env['REQUEST_METHOD']) 24 | 25 | status, headers, body = @app.call(env) 26 | headers = Utils::HeaderHash.new(headers) 27 | if etag_matches?(env, headers) || modified_since?(env, headers) 28 | status = 304 29 | headers.delete('Content-Type') 30 | headers.delete('Content-Length') 31 | body = [] 32 | end 33 | [status, headers, body] 34 | end 35 | 36 | private 37 | def etag_matches?(env, headers) 38 | etag = headers['Etag'] and etag == env['HTTP_IF_NONE_MATCH'] 39 | end 40 | 41 | def modified_since?(env, headers) 42 | last_modified = headers['Last-Modified'] and 43 | last_modified == env['HTTP_IF_MODIFIED_SINCE'] 44 | end 45 | end 46 | 47 | end 48 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_directory.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | 3 | require 'rack/directory' 4 | require 'rack/lint' 5 | 6 | require 'rack/mock' 7 | 8 | context "Rack::Directory" do 9 | DOCROOT = File.expand_path(File.dirname(__FILE__)) unless defined? DOCROOT 10 | FILE_CATCH = proc{|env| [200, {'Content-Type'=>'text/plain', "Content-Length" => "7"}, ['passed!']] } 11 | app = Rack::Directory.new DOCROOT, FILE_CATCH 12 | 13 | specify "serves directory indices" do 14 | res = Rack::MockRequest.new(Rack::Lint.new(app)). 15 | get("/cgi/") 16 | 17 | res.should.be.ok 18 | res.should =~ // 19 | end 20 | 21 | specify "passes to app if file found" do 22 | res = Rack::MockRequest.new(Rack::Lint.new(app)). 23 | get("/cgi/test") 24 | 25 | res.should.be.ok 26 | res.should =~ /passed!/ 27 | end 28 | 29 | specify "serves uri with URL encoded filenames" do 30 | res = Rack::MockRequest.new(Rack::Lint.new(app)). 31 | get("/%63%67%69/") # "/cgi/test" 32 | 33 | res.should.be.ok 34 | res.should =~ // 35 | 36 | res = Rack::MockRequest.new(Rack::Lint.new(app)). 37 | get("/cgi/%74%65%73%74") # "/cgi/test" 38 | 39 | res.should.be.ok 40 | res.should =~ /passed!/ 41 | end 42 | 43 | specify "does not allow directory traversal" do 44 | res = Rack::MockRequest.new(Rack::Lint.new(app)). 45 | get("/cgi/../test") 46 | 47 | res.should.be.forbidden 48 | 49 | res = Rack::MockRequest.new(Rack::Lint.new(app)). 50 | get("/cgi/%2E%2E/test") 51 | 52 | res.should.be.forbidden 53 | end 54 | 55 | specify "404s if it can't find the file" do 56 | res = Rack::MockRequest.new(Rack::Lint.new(app)). 57 | get("/cgi/blubb") 58 | 59 | res.should.be.not_found 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_commonlogger.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | require 'stringio' 3 | 4 | require 'rack/commonlogger' 5 | require 'rack/lobster' 6 | require 'rack/mock' 7 | 8 | context "Rack::CommonLogger" do 9 | app = lambda { |env| 10 | [200, 11 | {"Content-Type" => "text/html", "Content-Length" => length.to_s}, 12 | [obj]]} 13 | app_without_length = lambda { |env| 14 | [200, 15 | {"Content-Type" => "text/html"}, 16 | []]} 17 | app_with_zero_length = lambda { |env| 18 | [200, 19 | {"Content-Type" => "text/html", "Content-Length" => "0"}, 20 | []]} 21 | 22 | specify "should log to rack.errors by default" do 23 | res = Rack::MockRequest.new(Rack::CommonLogger.new(app)).get("/") 24 | 25 | res.errors.should.not.be.empty 26 | res.errors.should =~ /"GET \/ " 200 #{length} / 27 | end 28 | 29 | specify "should log to anything with +write+" do 30 | log = StringIO.new 31 | res = Rack::MockRequest.new(Rack::CommonLogger.new(app, log)).get("/") 32 | 33 | log.string.should =~ /"GET \/ " 200 #{length} / 34 | end 35 | 36 | specify "should log - content length if header is missing" do 37 | res = Rack::MockRequest.new(Rack::CommonLogger.new(app_without_length)).get("/") 38 | 39 | res.errors.should.not.be.empty 40 | res.errors.should =~ /"GET \/ " 200 - / 41 | end 42 | 43 | specify "should log - content length if header is zero" do 44 | res = Rack::MockRequest.new(Rack::CommonLogger.new(app_with_zero_length)).get("/") 45 | 46 | res.errors.should.not.be.empty 47 | res.errors.should =~ /"GET \/ " 200 - / 48 | end 49 | 50 | def length 51 | self.class.length 52 | end 53 | 54 | def self.length 55 | 123 56 | end 57 | 58 | def self.obj 59 | "hello world" 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/handler/cgi.rb: -------------------------------------------------------------------------------- 1 | require 'rack/content_length' 2 | 3 | module Rack 4 | module Handler 5 | class CGI 6 | def self.run(app, options=nil) 7 | serve app 8 | end 9 | 10 | def self.serve(app) 11 | app = ContentLength.new(app) 12 | 13 | env = ENV.to_hash 14 | env.delete "HTTP_CONTENT_LENGTH" 15 | 16 | env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/" 17 | 18 | env.update({"rack.version" => [1,1], 19 | "rack.input" => $stdin, 20 | "rack.errors" => $stderr, 21 | 22 | "rack.multithread" => false, 23 | "rack.multiprocess" => true, 24 | "rack.run_once" => true, 25 | 26 | "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http" 27 | }) 28 | 29 | env["QUERY_STRING"] ||= "" 30 | env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"] 31 | env["REQUEST_PATH"] ||= "/" 32 | 33 | status, headers, body = app.call(env) 34 | begin 35 | send_headers status, headers 36 | send_body body 37 | ensure 38 | body.close if body.respond_to? :close 39 | end 40 | end 41 | 42 | def self.send_headers(status, headers) 43 | STDOUT.print "Status: #{status}\r\n" 44 | headers.each { |k, vs| 45 | vs.split("\n").each { |v| 46 | STDOUT.print "#{k}: #{v}\r\n" 47 | } 48 | } 49 | STDOUT.print "\r\n" 50 | STDOUT.flush 51 | end 52 | 53 | def self.send_body(body) 54 | body.each { |part| 55 | STDOUT.print part 56 | STDOUT.flush 57 | } 58 | end 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/builder_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/helper' 2 | require 'builder' 3 | 4 | class BuilderTest < Test::Unit::TestCase 5 | def builder_app(&block) 6 | mock_app { 7 | set :views, File.dirname(__FILE__) + '/views' 8 | get '/', &block 9 | } 10 | get '/' 11 | end 12 | 13 | it 'renders inline Builder strings' do 14 | builder_app { builder 'xml.instruct!' } 15 | assert ok? 16 | assert_equal %{\n}, body 17 | end 18 | 19 | it 'renders inline blocks' do 20 | builder_app { 21 | @name = "Frank & Mary" 22 | builder do |xml| 23 | xml.couple @name 24 | end 25 | } 26 | assert ok? 27 | assert_equal "Frank & Mary\n", body 28 | end 29 | 30 | it 'renders .builder files in views path' do 31 | builder_app { 32 | @name = "Blue" 33 | builder :hello 34 | } 35 | assert ok? 36 | assert_equal %(You're my boy, Blue!\n), body 37 | end 38 | 39 | it "renders with inline layouts" do 40 | mock_app { 41 | layout do 42 | %(xml.layout { xml << yield }) 43 | end 44 | get('/') { builder %(xml.em 'Hello World') } 45 | } 46 | get '/' 47 | assert ok? 48 | assert_equal "\nHello World\n\n", body 49 | end 50 | 51 | it "renders with file layouts" do 52 | builder_app { 53 | builder %(xml.em 'Hello World'), :layout => :layout2 54 | } 55 | assert ok? 56 | assert_equal "\nHello World\n\n", body 57 | end 58 | 59 | it "raises error if template not found" do 60 | mock_app { 61 | get('/') { builder :no_such_template } 62 | } 63 | assert_raise(Errno::ENOENT) { get('/') } 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/contest.rb: -------------------------------------------------------------------------------- 1 | require "test/unit" 2 | 3 | # Test::Unit loads a default test if the suite is empty, and the only 4 | # purpose of that test is to fail. As having empty contexts is a common 5 | # practice, we decided to overwrite TestSuite#empty? in order to 6 | # allow them. Having a failure when no tests have been defined seems 7 | # counter-intuitive. 8 | class Test::Unit::TestSuite 9 | unless method_defined?(:empty?) 10 | def empty? 11 | false 12 | end 13 | end 14 | end 15 | 16 | # We added setup, test and context as class methods, and the instance 17 | # method setup now iterates on the setup blocks. Note that all setup 18 | # blocks must be defined with the block syntax. Adding a setup instance 19 | # method defeats the purpose of this library. 20 | class Test::Unit::TestCase 21 | def self.setup(&block) 22 | setup_blocks << block 23 | end 24 | 25 | def setup 26 | self.class.setup_blocks.each do |block| 27 | instance_eval(&block) 28 | end 29 | end 30 | 31 | def self.context(name, &block) 32 | subclass = Class.new(self.superclass) 33 | subclass.setup_blocks.unshift(*setup_blocks) 34 | subclass.class_eval(&block) 35 | const_set(context_name(name), subclass) 36 | end 37 | 38 | def self.test(name, &block) 39 | define_method(test_name(name), &block) 40 | end 41 | 42 | class << self 43 | alias_method :should, :test 44 | alias_method :describe, :context 45 | end 46 | 47 | private 48 | 49 | def self.setup_blocks 50 | @setup_blocks ||= [] 51 | end 52 | 53 | def self.context_name(name) 54 | "Test#{sanitize_name(name).gsub(/(^| )(\w)/) { $2.upcase }}".to_sym 55 | end 56 | 57 | def self.test_name(name) 58 | "test_#{sanitize_name(name).gsub(/\s+/,'_')}".to_sym 59 | end 60 | 61 | def self.sanitize_name(name) 62 | name.gsub(/\W+/, ' ').strip 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/handler/lsws.rb: -------------------------------------------------------------------------------- 1 | require 'lsapi' 2 | require 'rack/content_length' 3 | require 'rack/rewindable_input' 4 | 5 | module Rack 6 | module Handler 7 | class LSWS 8 | def self.run(app, options=nil) 9 | while LSAPI.accept != nil 10 | serve app 11 | end 12 | end 13 | def self.serve(app) 14 | app = Rack::ContentLength.new(app) 15 | 16 | env = ENV.to_hash 17 | env.delete "HTTP_CONTENT_LENGTH" 18 | env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/" 19 | 20 | rack_input = RewindableInput.new($stdin.read.to_s) 21 | 22 | env.update( 23 | "rack.version" => [1,1], 24 | "rack.input" => rack_input, 25 | "rack.errors" => $stderr, 26 | "rack.multithread" => false, 27 | "rack.multiprocess" => true, 28 | "rack.run_once" => false, 29 | "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http" 30 | ) 31 | 32 | env["QUERY_STRING"] ||= "" 33 | env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"] 34 | env["REQUEST_PATH"] ||= "/" 35 | status, headers, body = app.call(env) 36 | begin 37 | send_headers status, headers 38 | send_body body 39 | ensure 40 | body.close if body.respond_to? :close 41 | end 42 | ensure 43 | rack_input.close 44 | end 45 | def self.send_headers(status, headers) 46 | print "Status: #{status}\r\n" 47 | headers.each { |k, vs| 48 | vs.split("\n").each { |v| 49 | print "#{k}: #{v}\r\n" 50 | } 51 | } 52 | print "\r\n" 53 | STDOUT.flush 54 | end 55 | def self.send_body(body) 56 | body.each { |part| 57 | print part 58 | STDOUT.flush 59 | } 60 | end 61 | end 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_content_length.rb: -------------------------------------------------------------------------------- 1 | require 'rack/mock' 2 | require 'rack/content_length' 3 | 4 | context "Rack::ContentLength" do 5 | specify "sets Content-Length on String bodies if none is set" do 6 | app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] } 7 | response = Rack::ContentLength.new(app).call({}) 8 | response[1]['Content-Length'].should.equal '13' 9 | end 10 | 11 | specify "sets Content-Length on Array bodies if none is set" do 12 | app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] } 13 | response = Rack::ContentLength.new(app).call({}) 14 | response[1]['Content-Length'].should.equal '13' 15 | end 16 | 17 | specify "does not set Content-Length on variable length bodies" do 18 | body = lambda { "Hello World!" } 19 | def body.each ; yield call ; end 20 | 21 | app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, body] } 22 | response = Rack::ContentLength.new(app).call({}) 23 | response[1]['Content-Length'].should.be.nil 24 | end 25 | 26 | specify "does not change Content-Length if it is already set" do 27 | app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Content-Length' => '1'}, "Hello, World!"] } 28 | response = Rack::ContentLength.new(app).call({}) 29 | response[1]['Content-Length'].should.equal '1' 30 | end 31 | 32 | specify "does not set Content-Length on 304 responses" do 33 | app = lambda { |env| [304, {'Content-Type' => 'text/plain'}, []] } 34 | response = Rack::ContentLength.new(app).call({}) 35 | response[1]['Content-Length'].should.equal nil 36 | end 37 | 38 | specify "does not set Content-Length when Transfer-Encoding is chunked" do 39 | app = lambda { |env| [200, {'Transfer-Encoding' => 'chunked'}, []] } 40 | response = Rack::ContentLength.new(app).call({}) 41 | response[1]['Content-Length'].should.equal nil 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/helper.rb: -------------------------------------------------------------------------------- 1 | ENV['RACK_ENV'] = 'test' 2 | 3 | begin 4 | require 'rack' 5 | rescue LoadError 6 | require 'rubygems' 7 | require 'rack' 8 | end 9 | 10 | testdir = File.dirname(__FILE__) 11 | $LOAD_PATH.unshift testdir unless $LOAD_PATH.include?(testdir) 12 | 13 | libdir = File.dirname(File.dirname(__FILE__)) + '/lib' 14 | $LOAD_PATH.unshift libdir unless $LOAD_PATH.include?(libdir) 15 | 16 | require 'contest' 17 | require 'rack/test' 18 | require 'sinatra/base' 19 | 20 | class Sinatra::Base 21 | # Allow assertions in request context 22 | include Test::Unit::Assertions 23 | end 24 | 25 | Sinatra::Base.set :environment, :test 26 | 27 | class Test::Unit::TestCase 28 | include Rack::Test::Methods 29 | 30 | class << self 31 | alias_method :it, :test 32 | end 33 | 34 | alias_method :response, :last_response 35 | 36 | setup do 37 | Sinatra::Base.set :environment, :test 38 | end 39 | 40 | # Sets up a Sinatra::Base subclass defined with the block 41 | # given. Used in setup or individual spec methods to establish 42 | # the application. 43 | def mock_app(base=Sinatra::Base, &block) 44 | @app = Sinatra.new(base, &block) 45 | end 46 | 47 | def app 48 | Rack::Lint.new(@app) 49 | end 50 | 51 | def body 52 | response.body.to_s 53 | end 54 | 55 | # Delegate other missing methods to response. 56 | def method_missing(name, *args, &block) 57 | if response && response.respond_to?(name) 58 | response.send(name, *args, &block) 59 | else 60 | super 61 | end 62 | end 63 | 64 | # Also check response since we delegate there. 65 | def respond_to?(symbol, include_private=false) 66 | super || (response && response.respond_to?(symbol, include_private)) 67 | end 68 | 69 | # Do not output warnings for the duration of the block. 70 | def silence_warnings 71 | $VERBOSE, v = nil, $VERBOSE 72 | yield 73 | ensure 74 | $VERBOSE = v 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/middleware_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/helper' 2 | 3 | class MiddlewareTest < Test::Unit::TestCase 4 | setup do 5 | @app = mock_app(Sinatra::Application) { 6 | get '/*' do 7 | response.headers['X-Tests'] = env['test.ran']. 8 | map { |n| n.split('::').last }. 9 | join(', ') 10 | env['PATH_INFO'] 11 | end 12 | } 13 | end 14 | 15 | class MockMiddleware < Struct.new(:app) 16 | def call(env) 17 | (env['test.ran'] ||= []) << self.class.to_s 18 | app.call(env) 19 | end 20 | end 21 | 22 | class UpcaseMiddleware < MockMiddleware 23 | def call(env) 24 | env['PATH_INFO'] = env['PATH_INFO'].upcase 25 | super 26 | end 27 | end 28 | 29 | it "is added with Sinatra::Application.use" do 30 | @app.use UpcaseMiddleware 31 | get '/hello-world' 32 | assert ok? 33 | assert_equal '/HELLO-WORLD', body 34 | end 35 | 36 | class DowncaseMiddleware < MockMiddleware 37 | def call(env) 38 | env['PATH_INFO'] = env['PATH_INFO'].downcase 39 | super 40 | end 41 | end 42 | 43 | it "runs in the order defined" do 44 | @app.use UpcaseMiddleware 45 | @app.use DowncaseMiddleware 46 | get '/Foo' 47 | assert_equal "/foo", body 48 | assert_equal "UpcaseMiddleware, DowncaseMiddleware", response['X-Tests'] 49 | end 50 | 51 | it "resets the prebuilt pipeline when new middleware is added" do 52 | @app.use UpcaseMiddleware 53 | get '/Foo' 54 | assert_equal "/FOO", body 55 | @app.use DowncaseMiddleware 56 | get '/Foo' 57 | assert_equal '/foo', body 58 | assert_equal "UpcaseMiddleware, DowncaseMiddleware", response['X-Tests'] 59 | end 60 | 61 | it "works when app is used as middleware" do 62 | @app.use UpcaseMiddleware 63 | @app = @app.new 64 | get '/Foo' 65 | assert_equal "/FOO", body 66 | assert_equal "UpcaseMiddleware", response['X-Tests'] 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/recursive.rb: -------------------------------------------------------------------------------- 1 | require 'uri' 2 | 3 | module Rack 4 | # Rack::ForwardRequest gets caught by Rack::Recursive and redirects 5 | # the current request to the app at +url+. 6 | # 7 | # raise ForwardRequest.new("/not-found") 8 | # 9 | 10 | class ForwardRequest < Exception 11 | attr_reader :url, :env 12 | 13 | def initialize(url, env={}) 14 | @url = URI(url) 15 | @env = env 16 | 17 | @env["PATH_INFO"] = @url.path 18 | @env["QUERY_STRING"] = @url.query if @url.query 19 | @env["HTTP_HOST"] = @url.host if @url.host 20 | @env["HTTP_PORT"] = @url.port if @url.port 21 | @env["rack.url_scheme"] = @url.scheme if @url.scheme 22 | 23 | super "forwarding to #{url}" 24 | end 25 | end 26 | 27 | # Rack::Recursive allows applications called down the chain to 28 | # include data from other applications (by using 29 | # rack['rack.recursive.include'][...] or raise a 30 | # ForwardRequest to redirect internally. 31 | 32 | class Recursive 33 | def initialize(app) 34 | @app = app 35 | end 36 | 37 | def call(env) 38 | @script_name = env["SCRIPT_NAME"] 39 | @app.call(env.merge('rack.recursive.include' => method(:include))) 40 | rescue ForwardRequest => req 41 | call(env.merge(req.env)) 42 | end 43 | 44 | def include(env, path) 45 | unless path.index(@script_name) == 0 && (path[@script_name.size] == ?/ || 46 | path[@script_name.size].nil?) 47 | raise ArgumentError, "can only include below #{@script_name}, not #{path}" 48 | end 49 | 50 | env = env.merge("PATH_INFO" => path, "SCRIPT_NAME" => @script_name, 51 | "REQUEST_METHOD" => "GET", 52 | "CONTENT_LENGTH" => "0", "CONTENT_TYPE" => "", 53 | "rack.input" => StringIO.new("")) 54 | @app.call(env) 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_cascade.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | 3 | require 'rack/cascade' 4 | require 'rack/mock' 5 | 6 | require 'rack/urlmap' 7 | require 'rack/file' 8 | 9 | context "Rack::Cascade" do 10 | docroot = File.expand_path(File.dirname(__FILE__)) 11 | app1 = Rack::File.new(docroot) 12 | 13 | app2 = Rack::URLMap.new("/crash" => lambda { |env| raise "boom" }) 14 | 15 | app3 = Rack::URLMap.new("/foo" => lambda { |env| 16 | [200, { "Content-Type" => "text/plain"}, [""]]}) 17 | 18 | specify "should dispatch onward on 404 by default" do 19 | cascade = Rack::Cascade.new([app1, app2, app3]) 20 | Rack::MockRequest.new(cascade).get("/cgi/test").should.be.ok 21 | Rack::MockRequest.new(cascade).get("/foo").should.be.ok 22 | Rack::MockRequest.new(cascade).get("/toobad").should.be.not_found 23 | Rack::MockRequest.new(cascade).get("/cgi/../bla").should.be.forbidden 24 | end 25 | 26 | specify "should dispatch onward on whatever is passed" do 27 | cascade = Rack::Cascade.new([app1, app2, app3], [404, 403]) 28 | Rack::MockRequest.new(cascade).get("/cgi/../bla").should.be.not_found 29 | end 30 | 31 | specify "should return 404 if empty" do 32 | Rack::MockRequest.new(Rack::Cascade.new([])).get('/').should.be.not_found 33 | end 34 | 35 | specify "should append new app" do 36 | cascade = Rack::Cascade.new([], [404, 403]) 37 | Rack::MockRequest.new(cascade).get('/').should.be.not_found 38 | cascade << app2 39 | Rack::MockRequest.new(cascade).get('/cgi/test').should.be.not_found 40 | Rack::MockRequest.new(cascade).get('/cgi/../bla').should.be.not_found 41 | cascade << app1 42 | Rack::MockRequest.new(cascade).get('/cgi/test').should.be.ok 43 | Rack::MockRequest.new(cascade).get('/cgi/../bla').should.be.forbidden 44 | Rack::MockRequest.new(cascade).get('/foo').should.be.not_found 45 | cascade << app3 46 | Rack::MockRequest.new(cascade).get('/foo').should.be.ok 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/erb_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/helper' 2 | 3 | class ERBTest < Test::Unit::TestCase 4 | def erb_app(&block) 5 | mock_app { 6 | set :views, File.dirname(__FILE__) + '/views' 7 | get '/', &block 8 | } 9 | get '/' 10 | end 11 | 12 | it 'renders inline ERB strings' do 13 | erb_app { erb '<%= 1 + 1 %>' } 14 | assert ok? 15 | assert_equal '2', body 16 | end 17 | 18 | it 'renders .erb files in views path' do 19 | erb_app { erb :hello } 20 | assert ok? 21 | assert_equal "Hello World\n", body 22 | end 23 | 24 | it 'takes a :locals option' do 25 | erb_app { 26 | locals = {:foo => 'Bar'} 27 | erb '<%= foo %>', :locals => locals 28 | } 29 | assert ok? 30 | assert_equal 'Bar', body 31 | end 32 | 33 | it "renders with inline layouts" do 34 | mock_app { 35 | layout { 'THIS. IS. <%= yield.upcase %>!' } 36 | get('/') { erb 'Sparta' } 37 | } 38 | get '/' 39 | assert ok? 40 | assert_equal 'THIS. IS. SPARTA!', body 41 | end 42 | 43 | it "renders with file layouts" do 44 | erb_app { 45 | erb 'Hello World', :layout => :layout2 46 | } 47 | assert ok? 48 | assert_equal "ERB Layout!\nHello World\n", body 49 | end 50 | 51 | it "renders erb with blocks" do 52 | mock_app { 53 | def container 54 | @_out_buf << "THIS." 55 | yield 56 | @_out_buf << "SPARTA!" 57 | end 58 | def is; "IS." end 59 | get '/' do 60 | erb '<% container do %> <%= is %> <% end %>' 61 | end 62 | } 63 | get '/' 64 | assert ok? 65 | assert_equal 'THIS. IS. SPARTA!', body 66 | end 67 | 68 | it "can be used in a nested fashion for partials and whatnot" do 69 | mock_app { 70 | template(:inner) { "<%= 'hi' %>" } 71 | template(:outer) { "<%= erb :inner %>" } 72 | get '/' do 73 | erb :outer 74 | end 75 | } 76 | 77 | get '/' 78 | assert ok? 79 | assert_equal 'hi', body 80 | end 81 | end 82 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/urlmap.rb: -------------------------------------------------------------------------------- 1 | module Rack 2 | # Rack::URLMap takes a hash mapping urls or paths to apps, and 3 | # dispatches accordingly. Support for HTTP/1.1 host names exists if 4 | # the URLs start with http:// or https://. 5 | # 6 | # URLMap modifies the SCRIPT_NAME and PATH_INFO such that the part 7 | # relevant for dispatch is in the SCRIPT_NAME, and the rest in the 8 | # PATH_INFO. This should be taken care of when you need to 9 | # reconstruct the URL in order to create links. 10 | # 11 | # URLMap dispatches in such a way that the longest paths are tried 12 | # first, since they are most specific. 13 | 14 | class URLMap 15 | def initialize(map = {}) 16 | remap(map) 17 | end 18 | 19 | def remap(map) 20 | @mapping = map.map { |location, app| 21 | if location =~ %r{\Ahttps?://(.*?)(/.*)} 22 | host, location = $1, $2 23 | else 24 | host = nil 25 | end 26 | 27 | unless location[0] == ?/ 28 | raise ArgumentError, "paths need to start with /" 29 | end 30 | location = location.chomp('/') 31 | match = Regexp.new("^#{Regexp.quote(location).gsub('/', '/+')}(.*)", nil, 'n') 32 | 33 | [host, location, match, app] 34 | }.sort_by { |(h, l, m, a)| [h ? -h.size : (-1.0 / 0.0), -l.size] } # Longest path first 35 | end 36 | 37 | def call(env) 38 | path = env["PATH_INFO"].to_s 39 | script_name = env['SCRIPT_NAME'] 40 | hHost, sName, sPort = env.values_at('HTTP_HOST','SERVER_NAME','SERVER_PORT') 41 | @mapping.each { |host, location, match, app| 42 | next unless (hHost == host || sName == host \ 43 | || (host.nil? && (hHost == sName || hHost == sName+':'+sPort))) 44 | next unless path =~ match && rest = $1 45 | next unless rest.empty? || rest[0] == ?/ 46 | 47 | return app.call( 48 | env.merge( 49 | 'SCRIPT_NAME' => (script_name + location), 50 | 'PATH_INFO' => rest)) 51 | } 52 | [404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path}"]] 53 | end 54 | end 55 | end 56 | 57 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/lobster.rb: -------------------------------------------------------------------------------- 1 | require 'zlib' 2 | 3 | require 'rack/request' 4 | require 'rack/response' 5 | 6 | module Rack 7 | # Paste has a Pony, Rack has a Lobster! 8 | class Lobster 9 | LobsterString = Zlib::Inflate.inflate("eJx9kEEOwyAMBO99xd7MAcytUhPlJyj2 10 | P6jy9i4k9EQyGAnBarEXeCBqSkntNXsi/ZCvC48zGQoZKikGrFMZvgS5ZHd+aGWVuWwhVF0 11 | t1drVmiR42HcWNz5w3QanT+2gIvTVCiE1lm1Y0eU4JGmIIbaKwextKn8rvW+p5PIwFl8ZWJ 12 | I8jyiTlhTcYXkekJAzTyYN6E08A+dk8voBkAVTJQ==".delete("\n ").unpack("m*")[0]) 13 | 14 | LambdaLobster = lambda { |env| 15 | if env["QUERY_STRING"].include?("flip") 16 | lobster = LobsterString.split("\n"). 17 | map { |line| line.ljust(42).reverse }. 18 | join("\n") 19 | href = "?" 20 | else 21 | lobster = LobsterString 22 | href = "?flip" 23 | end 24 | 25 | content = ["Lobstericious!", 26 | "
", lobster, "
", 27 | "flip!"] 28 | length = content.inject(0) { |a,e| a+e.size }.to_s 29 | [200, {"Content-Type" => "text/html", "Content-Length" => length}, content] 30 | } 31 | 32 | def call(env) 33 | req = Request.new(env) 34 | if req.GET["flip"] == "left" 35 | lobster = LobsterString.split("\n"). 36 | map { |line| line.ljust(42).reverse }. 37 | join("\n") 38 | href = "?flip=right" 39 | elsif req.GET["flip"] == "crash" 40 | raise "Lobster crashed" 41 | else 42 | lobster = LobsterString 43 | href = "?flip=left" 44 | end 45 | 46 | res = Response.new 47 | res.write "Lobstericious!" 48 | res.write "
"
49 |       res.write lobster
50 |       res.write "
" 51 | res.write "

flip!

" 52 | res.write "

crash!

" 53 | res.finish 54 | end 55 | 56 | end 57 | end 58 | 59 | if $0 == __FILE__ 60 | require 'rack' 61 | require 'rack/showexceptions' 62 | Rack::Handler::WEBrick.run \ 63 | Rack::ShowExceptions.new(Rack::Lint.new(Rack::Lobster.new)), 64 | :Port => 9292 65 | end 66 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/erubis_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/helper' 2 | require 'erubis' 3 | 4 | class ERubisTest < Test::Unit::TestCase 5 | def erubis_app(&block) 6 | mock_app { 7 | set :views, File.dirname(__FILE__) + '/views' 8 | get '/', &block 9 | } 10 | get '/' 11 | end 12 | 13 | it 'renders inline ERubis strings' do 14 | erubis_app { erubis '<%= 1 + 1 %>' } 15 | assert ok? 16 | assert_equal '2', body 17 | end 18 | 19 | it 'renders .erubis files in views path' do 20 | erubis_app { erubis :hello } 21 | assert ok? 22 | assert_equal "Hello World\n", body 23 | end 24 | 25 | it 'takes a :locals option' do 26 | erubis_app { 27 | locals = {:foo => 'Bar'} 28 | erubis '<%= foo %>', :locals => locals 29 | } 30 | assert ok? 31 | assert_equal 'Bar', body 32 | end 33 | 34 | it "renders with inline layouts" do 35 | mock_app { 36 | layout { 'THIS. IS. <%= yield.upcase %>!' } 37 | get('/') { erubis 'Sparta' } 38 | } 39 | get '/' 40 | assert ok? 41 | assert_equal 'THIS. IS. SPARTA!', body 42 | end 43 | 44 | it "renders with file layouts" do 45 | erubis_app { 46 | erubis 'Hello World', :layout => :layout2 47 | } 48 | assert ok? 49 | assert_equal "ERubis Layout!\nHello World\n", body 50 | end 51 | 52 | it "renders erubis with blocks" do 53 | mock_app { 54 | def container 55 | @_out_buf << "THIS." 56 | yield 57 | @_out_buf << "SPARTA!" 58 | end 59 | def is; "IS." end 60 | get '/' do 61 | erubis '<% container do %> <%= is %> <% end %>' 62 | end 63 | } 64 | get '/' 65 | assert ok? 66 | assert_equal 'THIS. IS. SPARTA!', body 67 | end 68 | 69 | it "can be used in a nested fashion for partials and whatnot" do 70 | mock_app { 71 | template(:inner) { "<%= 'hi' %>" } 72 | template(:outer) { "<%= erubis :inner %>" } 73 | get '/' do 74 | erubis :outer 75 | end 76 | } 77 | 78 | get '/' 79 | assert ok? 80 | assert_equal 'hi', body 81 | end 82 | end 83 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_file.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | 3 | require 'rack/file' 4 | require 'rack/lint' 5 | 6 | require 'rack/mock' 7 | 8 | context "Rack::File" do 9 | DOCROOT = File.expand_path(File.dirname(__FILE__)) unless defined? DOCROOT 10 | 11 | specify "serves files" do 12 | res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))). 13 | get("/cgi/test") 14 | 15 | res.should.be.ok 16 | res.should =~ /ruby/ 17 | end 18 | 19 | specify "sets Last-Modified header" do 20 | res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))). 21 | get("/cgi/test") 22 | 23 | path = File.join(DOCROOT, "/cgi/test") 24 | 25 | res.should.be.ok 26 | res["Last-Modified"].should.equal File.mtime(path).httpdate 27 | end 28 | 29 | specify "serves files with URL encoded filenames" do 30 | res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))). 31 | get("/cgi/%74%65%73%74") # "/cgi/test" 32 | 33 | res.should.be.ok 34 | res.should =~ /ruby/ 35 | end 36 | 37 | specify "does not allow directory traversal" do 38 | res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))). 39 | get("/cgi/../test") 40 | 41 | res.should.be.forbidden 42 | end 43 | 44 | specify "does not allow directory traversal with encoded periods" do 45 | res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))). 46 | get("/%2E%2E/README") 47 | 48 | res.should.be.forbidden 49 | end 50 | 51 | specify "404s if it can't find the file" do 52 | res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))). 53 | get("/cgi/blubb") 54 | 55 | res.should.be.not_found 56 | end 57 | 58 | specify "detects SystemCallErrors" do 59 | res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))). 60 | get("/cgi") 61 | 62 | res.should.be.not_found 63 | end 64 | 65 | specify "returns bodies that respond to #to_path" do 66 | env = Rack::MockRequest.env_for("/cgi/test") 67 | status, headers, body = Rack::File.new(DOCROOT).call(env) 68 | 69 | path = File.join(DOCROOT, "/cgi/test") 70 | 71 | status.should.equal 200 72 | body.should.respond_to :to_path 73 | body.to_path.should.equal path 74 | end 75 | end 76 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/handler/scgi.rb: -------------------------------------------------------------------------------- 1 | require 'scgi' 2 | require 'stringio' 3 | require 'rack/content_length' 4 | require 'rack/chunked' 5 | 6 | module Rack 7 | module Handler 8 | class SCGI < ::SCGI::Processor 9 | attr_accessor :app 10 | 11 | def self.run(app, options=nil) 12 | new(options.merge(:app=>app, 13 | :host=>options[:Host], 14 | :port=>options[:Port], 15 | :socket=>options[:Socket])).listen 16 | end 17 | 18 | def initialize(settings = {}) 19 | @app = Rack::Chunked.new(Rack::ContentLength.new(settings[:app])) 20 | @log = Object.new 21 | def @log.info(*args); end 22 | def @log.error(*args); end 23 | super(settings) 24 | end 25 | 26 | def process_request(request, input_body, socket) 27 | env = {}.replace(request) 28 | env.delete "HTTP_CONTENT_TYPE" 29 | env.delete "HTTP_CONTENT_LENGTH" 30 | env["REQUEST_PATH"], env["QUERY_STRING"] = env["REQUEST_URI"].split('?', 2) 31 | env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"] 32 | env["PATH_INFO"] = env["REQUEST_PATH"] 33 | env["QUERY_STRING"] ||= "" 34 | env["SCRIPT_NAME"] = "" 35 | 36 | rack_input = StringIO.new(input_body) 37 | rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding) 38 | 39 | env.update({"rack.version" => [1,1], 40 | "rack.input" => rack_input, 41 | "rack.errors" => $stderr, 42 | "rack.multithread" => true, 43 | "rack.multiprocess" => true, 44 | "rack.run_once" => false, 45 | 46 | "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http" 47 | }) 48 | status, headers, body = app.call(env) 49 | begin 50 | socket.write("Status: #{status}\r\n") 51 | headers.each do |k, vs| 52 | vs.split("\n").each { |v| socket.write("#{k}: #{v}\r\n")} 53 | end 54 | socket.write("\r\n") 55 | body.each {|s| socket.write(s)} 56 | ensure 57 | body.close if body.respond_to? :close 58 | end 59 | end 60 | end 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/builder.rb: -------------------------------------------------------------------------------- 1 | module Rack 2 | # Rack::Builder implements a small DSL to iteratively construct Rack 3 | # applications. 4 | # 5 | # Example: 6 | # 7 | # app = Rack::Builder.new { 8 | # use Rack::CommonLogger 9 | # use Rack::ShowExceptions 10 | # map "/lobster" do 11 | # use Rack::Lint 12 | # run Rack::Lobster.new 13 | # end 14 | # } 15 | # 16 | # Or 17 | # 18 | # app = Rack::Builder.app do 19 | # use Rack::CommonLogger 20 | # lambda { |env| [200, {'Content-Type' => 'text/plain'}, 'OK'] } 21 | # end 22 | # 23 | # +use+ adds a middleware to the stack, +run+ dispatches to an application. 24 | # You can use +map+ to construct a Rack::URLMap in a convenient way. 25 | 26 | class Builder 27 | def self.parse_file(config, opts = Server::Options.new) 28 | options = {} 29 | if config =~ /\.ru$/ 30 | cfgfile = ::File.read(config) 31 | if cfgfile[/^#\\(.*)/] && opts 32 | options = opts.parse! $1.split(/\s+/) 33 | end 34 | cfgfile.sub!(/^__END__\n.*/, '') 35 | app = eval "Rack::Builder.new {( " + cfgfile + "\n )}.to_app", 36 | TOPLEVEL_BINDING, config 37 | else 38 | require config 39 | app = Object.const_get(::File.basename(config, '.rb').capitalize) 40 | end 41 | return app, options 42 | end 43 | 44 | def initialize(&block) 45 | @ins = [] 46 | instance_eval(&block) if block_given? 47 | end 48 | 49 | def self.app(&block) 50 | self.new(&block).to_app 51 | end 52 | 53 | def use(middleware, *args, &block) 54 | @ins << lambda { |app| middleware.new(app, *args, &block) } 55 | end 56 | 57 | def run(app) 58 | @ins << app #lambda { |nothing| app } 59 | end 60 | 61 | def map(path, &block) 62 | if @ins.last.kind_of? Hash 63 | @ins.last[path] = self.class.new(&block).to_app 64 | else 65 | @ins << {} 66 | map(path, &block) 67 | end 68 | end 69 | 70 | def to_app 71 | @ins[-1] = Rack::URLMap.new(@ins.last) if Hash === @ins.last 72 | inner_app = @ins.last 73 | @ins[0...-1].reverse.inject(inner_app) { |a, e| e.call(a) } 74 | end 75 | 76 | def call(env) 77 | to_app.call(env) 78 | end 79 | end 80 | end 81 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/result_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/helper' 2 | 3 | class ResultTest < Test::Unit::TestCase 4 | it "sets response.body when result is a String" do 5 | mock_app { 6 | get '/' do 7 | 'Hello World' 8 | end 9 | } 10 | 11 | get '/' 12 | assert ok? 13 | assert_equal 'Hello World', body 14 | end 15 | 16 | it "sets response.body when result is an Array of Strings" do 17 | mock_app { 18 | get '/' do 19 | ['Hello', 'World'] 20 | end 21 | } 22 | 23 | get '/' 24 | assert ok? 25 | assert_equal 'HelloWorld', body 26 | end 27 | 28 | it "sets response.body when result responds to #each" do 29 | mock_app { 30 | get '/' do 31 | res = lambda { 'Hello World' } 32 | def res.each ; yield call ; end 33 | res 34 | end 35 | } 36 | 37 | get '/' 38 | assert ok? 39 | assert_equal 'Hello World', body 40 | end 41 | 42 | it "sets response.body to [] when result is nil" do 43 | mock_app { 44 | get '/' do 45 | nil 46 | end 47 | } 48 | 49 | get '/' 50 | assert ok? 51 | assert_equal '', body 52 | end 53 | 54 | it "sets status, headers, and body when result is a Rack response tuple" do 55 | mock_app { 56 | get '/' do 57 | [205, {'Content-Type' => 'foo/bar'}, 'Hello World'] 58 | end 59 | } 60 | 61 | get '/' 62 | assert_equal 205, status 63 | assert_equal 'foo/bar', response['Content-Type'] 64 | assert_equal 'Hello World', body 65 | end 66 | 67 | it "sets status and body when result is a two-tuple" do 68 | mock_app { 69 | get '/' do 70 | [409, 'formula of'] 71 | end 72 | } 73 | 74 | get '/' 75 | assert_equal 409, status 76 | assert_equal 'formula of', body 77 | end 78 | 79 | it "raises a TypeError when result is a non two or three tuple Array" do 80 | mock_app { 81 | get '/' do 82 | [409, 'formula of', 'something else', 'even more'] 83 | end 84 | } 85 | 86 | assert_raise(TypeError) { get '/' } 87 | end 88 | 89 | it "sets status when result is a Fixnum status code" do 90 | mock_app { 91 | get('/') { 205 } 92 | } 93 | 94 | get '/' 95 | assert_equal 205, status 96 | assert_equal '', body 97 | end 98 | end 99 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/handler/webrick.rb: -------------------------------------------------------------------------------- 1 | require 'webrick' 2 | require 'stringio' 3 | require 'rack/content_length' 4 | 5 | module Rack 6 | module Handler 7 | class WEBrick < ::WEBrick::HTTPServlet::AbstractServlet 8 | def self.run(app, options={}) 9 | options[:BindAddress] = options.delete(:Host) if options[:Host] 10 | server = ::WEBrick::HTTPServer.new(options) 11 | server.mount "/", Rack::Handler::WEBrick, app 12 | trap(:INT) { server.shutdown } 13 | yield server if block_given? 14 | server.start 15 | end 16 | 17 | def initialize(server, app) 18 | super server 19 | @app = Rack::ContentLength.new(app) 20 | end 21 | 22 | def service(req, res) 23 | env = req.meta_vars 24 | env.delete_if { |k, v| v.nil? } 25 | 26 | rack_input = StringIO.new(req.body.to_s) 27 | rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding) 28 | 29 | env.update({"rack.version" => [1,1], 30 | "rack.input" => rack_input, 31 | "rack.errors" => $stderr, 32 | 33 | "rack.multithread" => true, 34 | "rack.multiprocess" => false, 35 | "rack.run_once" => false, 36 | 37 | "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http" 38 | }) 39 | 40 | env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"] 41 | env["QUERY_STRING"] ||= "" 42 | env["REQUEST_PATH"] ||= "/" 43 | unless env["PATH_INFO"] == "" 44 | path, n = req.request_uri.path, env["SCRIPT_NAME"].length 45 | env["PATH_INFO"] = path[n, path.length-n] 46 | end 47 | 48 | status, headers, body = @app.call(env) 49 | begin 50 | res.status = status.to_i 51 | headers.each { |k, vs| 52 | if k.downcase == "set-cookie" 53 | res.cookies.concat vs.split("\n") 54 | else 55 | vs.split("\n").each { |v| 56 | res[k] = v 57 | } 58 | end 59 | } 60 | body.each { |part| 61 | res.body << part 62 | } 63 | ensure 64 | body.close if body.respond_to? :close 65 | end 66 | end 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_methodoverride.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | 3 | require 'rack/mock' 4 | require 'rack/methodoverride' 5 | require 'stringio' 6 | 7 | context "Rack::MethodOverride" do 8 | specify "should not affect GET requests" do 9 | env = Rack::MockRequest.env_for("/?_method=delete", :method => "GET") 10 | app = Rack::MethodOverride.new(lambda { |env| Rack::Request.new(env) }) 11 | req = app.call(env) 12 | 13 | req.env["REQUEST_METHOD"].should.equal "GET" 14 | end 15 | 16 | specify "_method parameter should modify REQUEST_METHOD for POST requests" do 17 | env = Rack::MockRequest.env_for("/", :method => "POST", :input => "_method=put") 18 | app = Rack::MethodOverride.new(lambda { |env| Rack::Request.new(env) }) 19 | req = app.call(env) 20 | 21 | req.env["REQUEST_METHOD"].should.equal "PUT" 22 | end 23 | 24 | specify "X-HTTP-Method-Override header should modify REQUEST_METHOD for POST requests" do 25 | env = Rack::MockRequest.env_for("/", 26 | :method => "POST", 27 | "HTTP_X_HTTP_METHOD_OVERRIDE" => "PUT" 28 | ) 29 | app = Rack::MethodOverride.new(lambda { |env| Rack::Request.new(env) }) 30 | req = app.call(env) 31 | 32 | req.env["REQUEST_METHOD"].should.equal "PUT" 33 | end 34 | 35 | specify "should not modify REQUEST_METHOD if the method is unknown" do 36 | env = Rack::MockRequest.env_for("/", :method => "POST", :input => "_method=foo") 37 | app = Rack::MethodOverride.new(lambda { |env| Rack::Request.new(env) }) 38 | req = app.call(env) 39 | 40 | req.env["REQUEST_METHOD"].should.equal "POST" 41 | end 42 | 43 | specify "should not modify REQUEST_METHOD when _method is nil" do 44 | env = Rack::MockRequest.env_for("/", :method => "POST", :input => "foo=bar") 45 | app = Rack::MethodOverride.new(lambda { |env| Rack::Request.new(env) }) 46 | req = app.call(env) 47 | 48 | req.env["REQUEST_METHOD"].should.equal "POST" 49 | end 50 | 51 | specify "should store the original REQUEST_METHOD prior to overriding" do 52 | env = Rack::MockRequest.env_for("/", 53 | :method => "POST", 54 | :input => "_method=options") 55 | app = Rack::MethodOverride.new(lambda { |env| Rack::Request.new(env) }) 56 | req = app.call(env) 57 | 58 | req.env["rack.methodoverride.original_method"].should.equal "POST" 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_auth_basic.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | 3 | require 'rack/auth/basic' 4 | require 'rack/mock' 5 | 6 | context 'Rack::Auth::Basic' do 7 | 8 | def realm 9 | 'WallysWorld' 10 | end 11 | 12 | def unprotected_app 13 | lambda { |env| [ 200, {'Content-Type' => 'text/plain'}, ["Hi #{env['REMOTE_USER']}"] ] } 14 | end 15 | 16 | def protected_app 17 | app = Rack::Auth::Basic.new(unprotected_app) { |username, password| 'Boss' == username } 18 | app.realm = realm 19 | app 20 | end 21 | 22 | setup do 23 | @request = Rack::MockRequest.new(protected_app) 24 | end 25 | 26 | def request_with_basic_auth(username, password, &block) 27 | request 'HTTP_AUTHORIZATION' => 'Basic ' + ["#{username}:#{password}"].pack("m*"), &block 28 | end 29 | 30 | def request(headers = {}) 31 | yield @request.get('/', headers) 32 | end 33 | 34 | def assert_basic_auth_challenge(response) 35 | response.should.be.a.client_error 36 | response.status.should.equal 401 37 | response.should.include 'WWW-Authenticate' 38 | response.headers['WWW-Authenticate'].should =~ /Basic realm="#{Regexp.escape(realm)}"/ 39 | response.body.should.be.empty 40 | end 41 | 42 | specify 'should challenge correctly when no credentials are specified' do 43 | request do |response| 44 | assert_basic_auth_challenge response 45 | end 46 | end 47 | 48 | specify 'should rechallenge if incorrect credentials are specified' do 49 | request_with_basic_auth 'joe', 'password' do |response| 50 | assert_basic_auth_challenge response 51 | end 52 | end 53 | 54 | specify 'should return application output if correct credentials are specified' do 55 | request_with_basic_auth 'Boss', 'password' do |response| 56 | response.status.should.equal 200 57 | response.body.to_s.should.equal 'Hi Boss' 58 | end 59 | end 60 | 61 | specify 'should return 400 Bad Request if different auth scheme used' do 62 | request 'HTTP_AUTHORIZATION' => 'Digest params' do |response| 63 | response.should.be.a.client_error 64 | response.status.should.equal 400 65 | response.should.not.include 'WWW-Authenticate' 66 | end 67 | end 68 | 69 | specify 'realm as optional constructor arg' do 70 | app = Rack::Auth::Basic.new(unprotected_app, realm) { true } 71 | assert_equal realm, app.realm 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/file.rb: -------------------------------------------------------------------------------- 1 | require 'time' 2 | require 'rack/utils' 3 | require 'rack/mime' 4 | 5 | module Rack 6 | # Rack::File serves files below the +root+ given, according to the 7 | # path info of the Rack request. 8 | # 9 | # Handlers can detect if bodies are a Rack::File, and use mechanisms 10 | # like sendfile on the +path+. 11 | 12 | class File 13 | attr_accessor :root 14 | attr_accessor :path 15 | 16 | alias :to_path :path 17 | 18 | def initialize(root) 19 | @root = root 20 | end 21 | 22 | def call(env) 23 | dup._call(env) 24 | end 25 | 26 | F = ::File 27 | 28 | def _call(env) 29 | @path_info = Utils.unescape(env["PATH_INFO"]) 30 | return forbidden if @path_info.include? ".." 31 | 32 | @path = F.join(@root, @path_info) 33 | 34 | begin 35 | if F.file?(@path) && F.readable?(@path) 36 | serving 37 | else 38 | raise Errno::EPERM 39 | end 40 | rescue SystemCallError 41 | not_found 42 | end 43 | end 44 | 45 | def forbidden 46 | body = "Forbidden\n" 47 | [403, {"Content-Type" => "text/plain", 48 | "Content-Length" => body.size.to_s, 49 | "X-Cascade" => "pass"}, 50 | [body]] 51 | end 52 | 53 | # NOTE: 54 | # We check via File::size? whether this file provides size info 55 | # via stat (e.g. /proc files often don't), otherwise we have to 56 | # figure it out by reading the whole file into memory. And while 57 | # we're at it we also use this as body then. 58 | 59 | def serving 60 | if size = F.size?(@path) 61 | body = self 62 | else 63 | body = [F.read(@path)] 64 | size = Utils.bytesize(body.first) 65 | end 66 | 67 | [200, { 68 | "Last-Modified" => F.mtime(@path).httpdate, 69 | "Content-Type" => Mime.mime_type(F.extname(@path), 'text/plain'), 70 | "Content-Length" => size.to_s 71 | }, body] 72 | end 73 | 74 | def not_found 75 | body = "File not found: #{@path_info}\n" 76 | [404, {"Content-Type" => "text/plain", 77 | "Content-Length" => body.size.to_s, 78 | "X-Cascade" => "pass"}, 79 | [body]] 80 | end 81 | 82 | def each 83 | F.open(@path, "rb") { |file| 84 | while part = file.read(8192) 85 | yield part 86 | end 87 | } 88 | end 89 | end 90 | end 91 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_recursive.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | 3 | require 'rack/recursive' 4 | require 'rack/urlmap' 5 | require 'rack/response' 6 | require 'rack/mock' 7 | 8 | context "Rack::Recursive" do 9 | setup do 10 | 11 | @app1 = lambda { |env| 12 | res = Rack::Response.new 13 | res["X-Path-Info"] = env["PATH_INFO"] 14 | res["X-Query-String"] = env["QUERY_STRING"] 15 | res.finish do |res| 16 | res.write "App1" 17 | end 18 | } 19 | 20 | @app2 = lambda { |env| 21 | Rack::Response.new.finish do |res| 22 | res.write "App2" 23 | _, _, body = env['rack.recursive.include'].call(env, "/app1") 24 | body.each { |b| 25 | res.write b 26 | } 27 | end 28 | } 29 | 30 | @app3 = lambda { |env| 31 | raise Rack::ForwardRequest.new("/app1") 32 | } 33 | 34 | @app4 = lambda { |env| 35 | raise Rack::ForwardRequest.new("http://example.org/app1/quux?meh") 36 | } 37 | 38 | end 39 | 40 | specify "should allow for subrequests" do 41 | res = Rack::MockRequest.new(Rack::Recursive.new( 42 | Rack::URLMap.new("/app1" => @app1, 43 | "/app2" => @app2))). 44 | get("/app2") 45 | 46 | res.should.be.ok 47 | res.body.should.equal "App2App1" 48 | end 49 | 50 | specify "should raise error on requests not below the app" do 51 | app = Rack::URLMap.new("/app1" => @app1, 52 | "/app" => Rack::Recursive.new( 53 | Rack::URLMap.new("/1" => @app1, 54 | "/2" => @app2))) 55 | 56 | lambda { 57 | Rack::MockRequest.new(app).get("/app/2") 58 | }.should.raise(ArgumentError). 59 | message.should =~ /can only include below/ 60 | end 61 | 62 | specify "should support forwarding" do 63 | app = Rack::Recursive.new(Rack::URLMap.new("/app1" => @app1, 64 | "/app3" => @app3, 65 | "/app4" => @app4)) 66 | 67 | res = Rack::MockRequest.new(app).get("/app3") 68 | res.should.be.ok 69 | res.body.should.equal "App1" 70 | 71 | res = Rack::MockRequest.new(app).get("/app4") 72 | res.should.be.ok 73 | res.body.should.equal "App1" 74 | res["X-Path-Info"].should.equal "/quux" 75 | res["X-Query-String"].should.equal "meh" 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/AUTHORS: -------------------------------------------------------------------------------- 1 | Sinatra was designed and developed by Blake Mizerany (bmizerany) in 2 | California. Continued development would not be possible without the ongoing 3 | financial support provided by [Heroku](http://heroku.com) and the emotional 4 | support provided by Adam Wiggins (adamwiggins) of Heroku, Chris Wanstrath (defunkt), 5 | PJ Hyett (pjhyett), and the rest of the GitHub crew. 6 | 7 | Special thanks to the following extraordinary individuals, who-out which 8 | Sinatra would not be possible: 9 | 10 | * Ryan Tomayko (rtomayko) for constantly fixing whitespace errors 60d5006 11 | * Ezra Zygmuntowicz (ezmobius) for initial help and letting Blake steal 12 | some of merbs internal code. 13 | * Ari Lerner (http://xnot.org/) for his evangelism, spirit, and gumption 14 | that got Sinatra recognized from Day 1. 15 | * Christopher Schneid (cschneid) for The Book, the blog (gittr.com), 16 | irclogger.com, and a bunch of useful patches. 17 | * Markus Prinz (cypher) for patches over the years, caring about 18 | the README, and hanging in there when times were rough. 19 | * Simon Rozet (sr) for a ton of doc patches, HAML options, and all that 20 | advocacy stuff he's going to do for 1.0. 21 | * Erik Kastner (kastner) for fixing `MIME_TYPES` under Rack 0.5. 22 | * Ben Bleything (bleything) for caring about HTTP status codes and doc fixes. 23 | * Igal Koshevoy (igal) for root path detection under Thin/Passenger. 24 | * Jon Crosby (jcrosby) for coffee breaks, doc fixes, and just because, man. 25 | * Karel Minarik (karmi) for screaming until the website came back up. 26 | * Jeremy Evans (jeremyevans) for unbreaking optional path params (twice!) 27 | * The GitHub guys for stealing Blake's table. 28 | * Nickolas Means (nmeans) for Sass template support. 29 | * Victor Hugo Borja (vic) for splat'n routes specs and doco. 30 | * Avdi Grimm (avdi) for basic RSpec support. 31 | * Jack Danger Canty for a more accurate root directory and for making me 32 | watch [this](http://www.youtube.com/watch?v=ueaHLHgskkw) just now. 33 | * Mathew Walker for making escaped paths work with static files. 34 | * Millions of Us for having the problem that led to Sinatra's conception. 35 | * Songbird for the problems that helped Sinatra's future become realized. 36 | * Rick Olson (technoweenie) for the killer plug at RailsConf '08. 37 | * Steven Garcia for the amazing custom artwork you see on 404's and 500's 38 | * Pat Nakajima (nakajima) for fixing non-nested params in nested params Hash's. 39 | 40 | and last but not least: 41 | 42 | * Frank Sinatra (chairman of the board) for having so much class he 43 | deserves a web-framework named after him. 44 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_chunked.rb: -------------------------------------------------------------------------------- 1 | require 'rack/mock' 2 | require 'rack/chunked' 3 | require 'rack/utils' 4 | 5 | context "Rack::Chunked" do 6 | 7 | before do 8 | @env = Rack::MockRequest. 9 | env_for('/', 'HTTP_VERSION' => '1.1', 'REQUEST_METHOD' => 'GET') 10 | end 11 | 12 | specify 'chunks responses with no Content-Length' do 13 | app = lambda { |env| [200, {}, ['Hello', ' ', 'World!']] } 14 | response = Rack::MockResponse.new(*Rack::Chunked.new(app).call(@env)) 15 | response.headers.should.not.include 'Content-Length' 16 | response.headers['Transfer-Encoding'].should.equal 'chunked' 17 | response.body.should.equal "5\r\nHello\r\n1\r\n \r\n6\r\nWorld!\r\n0\r\n\r\n" 18 | end 19 | 20 | specify 'chunks empty bodies properly' do 21 | app = lambda { |env| [200, {}, []] } 22 | response = Rack::MockResponse.new(*Rack::Chunked.new(app).call(@env)) 23 | response.headers.should.not.include 'Content-Length' 24 | response.headers['Transfer-Encoding'].should.equal 'chunked' 25 | response.body.should.equal "0\r\n\r\n" 26 | end 27 | 28 | specify 'does not modify response when Content-Length header present' do 29 | app = lambda { |env| [200, {'Content-Length'=>'12'}, ['Hello', ' ', 'World!']] } 30 | status, headers, body = Rack::Chunked.new(app).call(@env) 31 | status.should.equal 200 32 | headers.should.not.include 'Transfer-Encoding' 33 | headers.should.include 'Content-Length' 34 | body.join.should.equal 'Hello World!' 35 | end 36 | 37 | specify 'does not modify response when client is HTTP/1.0' do 38 | app = lambda { |env| [200, {}, ['Hello', ' ', 'World!']] } 39 | @env['HTTP_VERSION'] = 'HTTP/1.0' 40 | status, headers, body = Rack::Chunked.new(app).call(@env) 41 | status.should.equal 200 42 | headers.should.not.include 'Transfer-Encoding' 43 | body.join.should.equal 'Hello World!' 44 | end 45 | 46 | specify 'does not modify response when Transfer-Encoding header already present' do 47 | app = lambda { |env| [200, {'Transfer-Encoding' => 'identity'}, ['Hello', ' ', 'World!']] } 48 | status, headers, body = Rack::Chunked.new(app).call(@env) 49 | status.should.equal 200 50 | headers['Transfer-Encoding'].should.equal 'identity' 51 | body.join.should.equal 'Hello World!' 52 | end 53 | 54 | [100, 204, 304].each do |status_code| 55 | specify "does not modify response when status code is #{status_code}" do 56 | app = lambda { |env| [status_code, {}, []] } 57 | status, headers, body = Rack::Chunked.new(app).call(@env) 58 | status.should.equal status_code 59 | headers.should.not.include 'Transfer-Encoding' 60 | end 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_builder.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | 3 | require 'rack/builder' 4 | require 'rack/mock' 5 | require 'rack/showexceptions' 6 | require 'rack/auth/basic' 7 | 8 | context "Rack::Builder" do 9 | specify "chains apps by default" do 10 | app = Rack::Builder.new do 11 | use Rack::ShowExceptions 12 | run lambda { |env| raise "bzzzt" } 13 | end.to_app 14 | 15 | Rack::MockRequest.new(app).get("/").should.be.server_error 16 | Rack::MockRequest.new(app).get("/").should.be.server_error 17 | Rack::MockRequest.new(app).get("/").should.be.server_error 18 | end 19 | 20 | specify "has implicit #to_app" do 21 | app = Rack::Builder.new do 22 | use Rack::ShowExceptions 23 | run lambda { |env| raise "bzzzt" } 24 | end 25 | 26 | Rack::MockRequest.new(app).get("/").should.be.server_error 27 | Rack::MockRequest.new(app).get("/").should.be.server_error 28 | Rack::MockRequest.new(app).get("/").should.be.server_error 29 | end 30 | 31 | specify "supports blocks on use" do 32 | app = Rack::Builder.new do 33 | use Rack::ShowExceptions 34 | use Rack::Auth::Basic do |username, password| 35 | 'secret' == password 36 | end 37 | 38 | run lambda { |env| [200, {}, ['Hi Boss']] } 39 | end 40 | 41 | response = Rack::MockRequest.new(app).get("/") 42 | response.should.be.client_error 43 | response.status.should.equal 401 44 | 45 | # with auth... 46 | response = Rack::MockRequest.new(app).get("/", 47 | 'HTTP_AUTHORIZATION' => 'Basic ' + ["joe:secret"].pack("m*")) 48 | response.status.should.equal 200 49 | response.body.to_s.should.equal 'Hi Boss' 50 | end 51 | 52 | specify "has explicit #to_app" do 53 | app = Rack::Builder.app do 54 | use Rack::ShowExceptions 55 | run lambda { |env| raise "bzzzt" } 56 | end 57 | 58 | Rack::MockRequest.new(app).get("/").should.be.server_error 59 | Rack::MockRequest.new(app).get("/").should.be.server_error 60 | Rack::MockRequest.new(app).get("/").should.be.server_error 61 | end 62 | 63 | specify "apps are initialized once" do 64 | app = Rack::Builder.new do 65 | class AppClass 66 | def initialize 67 | @called = 0 68 | end 69 | def call(env) 70 | raise "bzzzt" if @called > 0 71 | @called += 1 72 | [200, {'Content-Type' => 'text/plain'}, ['OK']] 73 | end 74 | end 75 | 76 | use Rack::ShowExceptions 77 | run AppClass.new 78 | end 79 | 80 | Rack::MockRequest.new(app).get("/").status.should.equal 200 81 | Rack::MockRequest.new(app).get("/").should.be.server_error 82 | end 83 | 84 | end 85 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/handler/fastcgi.rb: -------------------------------------------------------------------------------- 1 | require 'fcgi' 2 | require 'socket' 3 | require 'rack/content_length' 4 | require 'rack/rewindable_input' 5 | 6 | if defined? FCGI::Stream 7 | class FCGI::Stream 8 | alias _rack_read_without_buffer read 9 | 10 | def read(n, buffer=nil) 11 | buf = _rack_read_without_buffer n 12 | buffer.replace(buf.to_s) if buffer 13 | buf 14 | end 15 | end 16 | end 17 | 18 | module Rack 19 | module Handler 20 | class FastCGI 21 | def self.run(app, options={}) 22 | file = options[:File] and STDIN.reopen(UNIXServer.new(file)) 23 | port = options[:Port] and STDIN.reopen(TCPServer.new(port)) 24 | FCGI.each { |request| 25 | serve request, app 26 | } 27 | end 28 | 29 | def self.serve(request, app) 30 | app = Rack::ContentLength.new(app) 31 | 32 | env = request.env 33 | env.delete "HTTP_CONTENT_LENGTH" 34 | 35 | env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/" 36 | 37 | rack_input = RewindableInput.new(request.in) 38 | 39 | env.update({"rack.version" => [1,1], 40 | "rack.input" => rack_input, 41 | "rack.errors" => request.err, 42 | 43 | "rack.multithread" => false, 44 | "rack.multiprocess" => true, 45 | "rack.run_once" => false, 46 | 47 | "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http" 48 | }) 49 | 50 | env["QUERY_STRING"] ||= "" 51 | env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"] 52 | env["REQUEST_PATH"] ||= "/" 53 | env.delete "CONTENT_TYPE" if env["CONTENT_TYPE"] == "" 54 | env.delete "CONTENT_LENGTH" if env["CONTENT_LENGTH"] == "" 55 | 56 | begin 57 | status, headers, body = app.call(env) 58 | begin 59 | send_headers request.out, status, headers 60 | send_body request.out, body 61 | ensure 62 | body.close if body.respond_to? :close 63 | end 64 | ensure 65 | rack_input.close 66 | request.finish 67 | end 68 | end 69 | 70 | def self.send_headers(out, status, headers) 71 | out.print "Status: #{status}\r\n" 72 | headers.each { |k, vs| 73 | vs.split("\n").each { |v| 74 | out.print "#{k}: #{v}\r\n" 75 | } 76 | } 77 | out.print "\r\n" 78 | out.flush 79 | end 80 | 81 | def self.send_body(out, body) 82 | body.each { |part| 83 | out.print part 84 | out.flush 85 | } 86 | end 87 | end 88 | end 89 | end 90 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/haml_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/helper' 2 | 3 | begin 4 | require 'haml' 5 | 6 | class HAMLTest < Test::Unit::TestCase 7 | def haml_app(&block) 8 | mock_app { 9 | set :views, File.dirname(__FILE__) + '/views' 10 | get '/', &block 11 | } 12 | get '/' 13 | end 14 | 15 | it 'renders inline HAML strings' do 16 | haml_app { haml '%h1 Hiya' } 17 | assert ok? 18 | assert_equal "

Hiya

\n", body 19 | end 20 | 21 | it 'renders .haml files in views path' do 22 | haml_app { haml :hello } 23 | assert ok? 24 | assert_equal "

Hello From Haml

\n", body 25 | end 26 | 27 | it "renders with inline layouts" do 28 | mock_app { 29 | layout { %q(%h1= 'THIS. IS. ' + yield.upcase) } 30 | get('/') { haml '%em Sparta' } 31 | } 32 | get '/' 33 | assert ok? 34 | assert_equal "

THIS. IS. SPARTA

\n", body 35 | end 36 | 37 | it "renders with file layouts" do 38 | haml_app { 39 | haml 'Hello World', :layout => :layout2 40 | } 41 | assert ok? 42 | assert_equal "

HAML Layout!

\n

Hello World

\n", body 43 | end 44 | 45 | it "raises error if template not found" do 46 | mock_app { 47 | get('/') { haml :no_such_template } 48 | } 49 | assert_raise(Errno::ENOENT) { get('/') } 50 | end 51 | 52 | it "passes HAML options to the Haml engine" do 53 | mock_app { 54 | get '/' do 55 | haml "!!!\n%h1 Hello World", :format => :html5 56 | end 57 | } 58 | get '/' 59 | assert ok? 60 | assert_equal "\n

Hello World

\n", body 61 | end 62 | 63 | it "passes default HAML options to the Haml engine" do 64 | mock_app { 65 | set :haml, {:format => :html5} 66 | get '/' do 67 | haml "!!!\n%h1 Hello World" 68 | end 69 | } 70 | get '/' 71 | assert ok? 72 | assert_equal "\n

Hello World

\n", body 73 | end 74 | 75 | it "merges the default HAML options with the overrides and passes them to the Haml engine" do 76 | mock_app { 77 | set :haml, {:format => :html5, :attr_wrapper => '"'} # default HAML attr are 78 | get '/' do 79 | haml "!!!\n%h1{:class => :header} Hello World" 80 | end 81 | get '/html4' do 82 | haml "!!!\n%h1{:class => 'header'} Hello World", :format => :html4 83 | end 84 | } 85 | get '/' 86 | assert ok? 87 | assert_equal "\n

Hello World

\n", body 88 | get '/html4' 89 | assert ok? 90 | assert_match(/^ :layout2 } 29 | assert ok? 30 | assert_equal "#sass {\n background-color: #FFF; }\n", body 31 | end 32 | 33 | it "raises error if template not found" do 34 | mock_app { 35 | get('/') { sass :no_such_template } 36 | } 37 | assert_raise(Errno::ENOENT) { get('/') } 38 | end 39 | 40 | it "passes SASS options to the Sass engine" do 41 | sass_app { 42 | sass "#sass\n :background-color #FFF\n :color #000\n", :style => :compact 43 | } 44 | assert ok? 45 | assert_equal "#sass { background-color: #FFF; color: #000; }\n", body 46 | end 47 | 48 | it "passes default SASS options to the Sass engine" do 49 | mock_app { 50 | set :sass, {:style => :compact} # default Sass style is :nested 51 | get '/' do 52 | sass "#sass\n :background-color #FFF\n :color #000\n" 53 | end 54 | } 55 | get '/' 56 | assert ok? 57 | assert_equal "#sass { background-color: #FFF; color: #000; }\n", body 58 | end 59 | 60 | it "merges the default SASS options with the overrides and passes them to the Sass engine" do 61 | mock_app { 62 | set :sass, {:style => :compact, :attribute_syntax => :alternate } # default Sass attribute_syntax is :normal (with : in front) 63 | get '/' do 64 | sass "#sass\n background-color: #FFF\n color: #000\n" 65 | end 66 | get '/raised' do 67 | sass "#sass\n :background-color #FFF\n :color #000\n", :style => :expanded # retains global attribute_syntax settings 68 | end 69 | get '/expanded_normal' do 70 | sass "#sass\n :background-color #FFF\n :color #000\n", :style => :expanded, :attribute_syntax => :normal 71 | end 72 | } 73 | get '/' 74 | assert ok? 75 | assert_equal "#sass { background-color: #FFF; color: #000; }\n", body 76 | assert_raise(Sass::SyntaxError) { get('/raised') } 77 | get '/expanded_normal' 78 | assert ok? 79 | assert_equal "#sass {\n background-color: #FFF;\n color: #000;\n}\n", body 80 | end 81 | end 82 | 83 | rescue 84 | warn "#{$!.to_s}: skipping sass tests" 85 | end 86 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_sendfile.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | require 'rack/mock' 3 | require 'rack/sendfile' 4 | 5 | context "Rack::File" do 6 | specify "should respond to #to_path" do 7 | Rack::File.new(Dir.pwd).should.respond_to :to_path 8 | end 9 | end 10 | 11 | context "Rack::Sendfile" do 12 | def sendfile_body 13 | res = ['Hello World'] 14 | def res.to_path ; "/tmp/hello.txt" ; end 15 | res 16 | end 17 | 18 | def simple_app(body=sendfile_body) 19 | lambda { |env| [200, {'Content-Type' => 'text/plain'}, body] } 20 | end 21 | 22 | def sendfile_app(body=sendfile_body) 23 | Rack::Sendfile.new(simple_app(body)) 24 | end 25 | 26 | setup do 27 | @request = Rack::MockRequest.new(sendfile_app) 28 | end 29 | 30 | def request(headers={}) 31 | yield @request.get('/', headers) 32 | end 33 | 34 | specify "does nothing when no X-Sendfile-Type header present" do 35 | request do |response| 36 | response.should.be.ok 37 | response.body.should.equal 'Hello World' 38 | response.headers.should.not.include 'X-Sendfile' 39 | end 40 | end 41 | 42 | specify "sets X-Sendfile response header and discards body" do 43 | request 'HTTP_X_SENDFILE_TYPE' => 'X-Sendfile' do |response| 44 | response.should.be.ok 45 | response.body.should.be.empty 46 | response.headers['X-Sendfile'].should.equal '/tmp/hello.txt' 47 | end 48 | end 49 | 50 | specify "sets X-Lighttpd-Send-File response header and discards body" do 51 | request 'HTTP_X_SENDFILE_TYPE' => 'X-Lighttpd-Send-File' do |response| 52 | response.should.be.ok 53 | response.body.should.be.empty 54 | response.headers['X-Lighttpd-Send-File'].should.equal '/tmp/hello.txt' 55 | end 56 | end 57 | 58 | specify "sets X-Accel-Redirect response header and discards body" do 59 | headers = { 60 | 'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect', 61 | 'HTTP_X_ACCEL_MAPPING' => '/tmp/=/foo/bar/' 62 | } 63 | request headers do |response| 64 | response.should.be.ok 65 | response.body.should.be.empty 66 | response.headers['X-Accel-Redirect'].should.equal '/foo/bar/hello.txt' 67 | end 68 | end 69 | 70 | specify 'writes to rack.error when no X-Accel-Mapping is specified' do 71 | request 'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect' do |response| 72 | response.should.be.ok 73 | response.body.should.equal 'Hello World' 74 | response.headers.should.not.include 'X-Accel-Redirect' 75 | response.errors.should.include 'X-Accel-Mapping' 76 | end 77 | end 78 | 79 | specify 'does nothing when body does not respond to #to_path' do 80 | @request = Rack::MockRequest.new(sendfile_app(['Not a file...'])) 81 | request 'HTTP_X_SENDFILE_TYPE' => 'X-Sendfile' do |response| 82 | response.body.should.equal 'Not a file...' 83 | response.headers.should.not.include 'X-Sendfile' 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_cgi.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | require 'testrequest' 3 | 4 | context "Rack::Handler::CGI" do 5 | include TestRequest::Helpers 6 | 7 | setup do 8 | @host = '0.0.0.0' 9 | @port = 9203 10 | end 11 | 12 | # Keep this first. 13 | specify "startup" do 14 | $pid = fork { 15 | Dir.chdir(File.join(File.dirname(__FILE__), "..", "test", "cgi")) 16 | exec "lighttpd -D -f lighttpd.conf" 17 | } 18 | end 19 | 20 | specify "should respond" do 21 | sleep 1 22 | lambda { 23 | GET("/test") 24 | }.should.not.raise 25 | end 26 | 27 | specify "should be a lighttpd" do 28 | GET("/test") 29 | status.should.be 200 30 | response["SERVER_SOFTWARE"].should =~ /lighttpd/ 31 | response["HTTP_VERSION"].should.equal "HTTP/1.1" 32 | response["SERVER_PROTOCOL"].should.equal "HTTP/1.1" 33 | response["SERVER_PORT"].should.equal @port.to_s 34 | response["SERVER_NAME"].should =~ @host 35 | end 36 | 37 | specify "should have rack headers" do 38 | GET("/test") 39 | response["rack.version"].should.equal [1,1] 40 | response["rack.multithread"].should.be false 41 | response["rack.multiprocess"].should.be true 42 | response["rack.run_once"].should.be true 43 | end 44 | 45 | specify "should have CGI headers on GET" do 46 | GET("/test") 47 | response["REQUEST_METHOD"].should.equal "GET" 48 | response["SCRIPT_NAME"].should.equal "/test" 49 | response["REQUEST_PATH"].should.equal "/" 50 | response["PATH_INFO"].should.equal "" 51 | response["QUERY_STRING"].should.equal "" 52 | response["test.postdata"].should.equal "" 53 | 54 | GET("/test/foo?quux=1") 55 | response["REQUEST_METHOD"].should.equal "GET" 56 | response["SCRIPT_NAME"].should.equal "/test" 57 | response["REQUEST_PATH"].should.equal "/" 58 | response["PATH_INFO"].should.equal "/foo" 59 | response["QUERY_STRING"].should.equal "quux=1" 60 | end 61 | 62 | specify "should have CGI headers on POST" do 63 | POST("/test", {"rack-form-data" => "23"}, {'X-test-header' => '42'}) 64 | status.should.equal 200 65 | response["REQUEST_METHOD"].should.equal "POST" 66 | response["SCRIPT_NAME"].should.equal "/test" 67 | response["REQUEST_PATH"].should.equal "/" 68 | response["QUERY_STRING"].should.equal "" 69 | response["HTTP_X_TEST_HEADER"].should.equal "42" 70 | response["test.postdata"].should.equal "rack-form-data=23" 71 | end 72 | 73 | specify "should support HTTP auth" do 74 | GET("/test", {:user => "ruth", :passwd => "secret"}) 75 | response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ=" 76 | end 77 | 78 | specify "should set status" do 79 | GET("/test?secret") 80 | status.should.equal 403 81 | response["rack.url_scheme"].should.equal "http" 82 | end 83 | 84 | # Keep this last. 85 | specify "shutdown" do 86 | Process.kill 15, $pid 87 | Process.wait($pid).should.equal $pid 88 | end 89 | end 90 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_showstatus.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | 3 | require 'rack/showstatus' 4 | require 'rack/mock' 5 | 6 | context "Rack::ShowStatus" do 7 | specify "should provide a default status message" do 8 | req = Rack::MockRequest.new(Rack::ShowStatus.new(lambda { |env| 9 | [404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []] 10 | })) 11 | 12 | res = req.get("/", :lint => true) 13 | res.should.be.not_found 14 | res.should.be.not.empty 15 | 16 | res["Content-Type"].should.equal("text/html") 17 | res.should =~ /404/ 18 | res.should =~ /Not Found/ 19 | end 20 | 21 | specify "should let the app provide additional information" do 22 | req = Rack::MockRequest.new(Rack::ShowStatus.new(lambda { |env| 23 | env["rack.showstatus.detail"] = "gone too meta." 24 | [404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []] 25 | })) 26 | 27 | res = req.get("/", :lint => true) 28 | res.should.be.not_found 29 | res.should.be.not.empty 30 | 31 | res["Content-Type"].should.equal("text/html") 32 | res.should =~ /404/ 33 | res.should =~ /Not Found/ 34 | res.should =~ /too meta/ 35 | end 36 | 37 | specify "should not replace existing messages" do 38 | req = Rack::MockRequest.new(Rack::ShowStatus.new(lambda { |env| 39 | [404, {"Content-Type" => "text/plain", "Content-Length" => "4"}, ["foo!"]] 40 | })) 41 | res = req.get("/", :lint => true) 42 | res.should.be.not_found 43 | 44 | res.body.should == "foo!" 45 | end 46 | 47 | specify "should pass on original headers" do 48 | headers = {"WWW-Authenticate" => "Basic blah"} 49 | 50 | req = Rack::MockRequest.new(Rack::ShowStatus.new(lambda { |env| [401, headers, []] })) 51 | res = req.get("/", :lint => true) 52 | 53 | res["WWW-Authenticate"].should.equal("Basic blah") 54 | end 55 | 56 | specify "should replace existing messages if there is detail" do 57 | req = Rack::MockRequest.new(Rack::ShowStatus.new(lambda { |env| 58 | env["rack.showstatus.detail"] = "gone too meta." 59 | [404, {"Content-Type" => "text/plain", "Content-Length" => "4"}, ["foo!"]] 60 | })) 61 | 62 | res = req.get("/", :lint => true) 63 | res.should.be.not_found 64 | res.should.be.not.empty 65 | 66 | res["Content-Type"].should.equal("text/html") 67 | res["Content-Length"].should.not.equal("4") 68 | res.should =~ /404/ 69 | res.should =~ /too meta/ 70 | res.body.should.not =~ /foo/ 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_thin.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | 3 | begin 4 | require 'rack/handler/thin' 5 | require 'testrequest' 6 | require 'timeout' 7 | 8 | context "Rack::Handler::Thin" do 9 | include TestRequest::Helpers 10 | 11 | setup do 12 | @app = Rack::Lint.new(TestRequest.new) 13 | @server = nil 14 | Thin::Logging.silent = true 15 | @thread = Thread.new do 16 | Rack::Handler::Thin.run(@app, :Host => @host='0.0.0.0', :Port => @port=9204) do |server| 17 | @server = server 18 | end 19 | end 20 | Thread.pass until @server && @server.running? 21 | end 22 | 23 | specify "should respond" do 24 | lambda { 25 | GET("/") 26 | }.should.not.raise 27 | end 28 | 29 | specify "should be a Thin" do 30 | GET("/") 31 | status.should.be 200 32 | response["SERVER_SOFTWARE"].should =~ /thin/ 33 | response["HTTP_VERSION"].should.equal "HTTP/1.1" 34 | response["SERVER_PROTOCOL"].should.equal "HTTP/1.1" 35 | response["SERVER_PORT"].should.equal "9204" 36 | response["SERVER_NAME"].should.equal "0.0.0.0" 37 | end 38 | 39 | specify "should have rack headers" do 40 | GET("/") 41 | response["rack.version"].should.equal [0,3] 42 | response["rack.multithread"].should.be false 43 | response["rack.multiprocess"].should.be false 44 | response["rack.run_once"].should.be false 45 | end 46 | 47 | specify "should have CGI headers on GET" do 48 | GET("/") 49 | response["REQUEST_METHOD"].should.equal "GET" 50 | response["REQUEST_PATH"].should.equal "/" 51 | response["PATH_INFO"].should.be.equal "/" 52 | response["QUERY_STRING"].should.equal "" 53 | response["test.postdata"].should.equal "" 54 | 55 | GET("/test/foo?quux=1") 56 | response["REQUEST_METHOD"].should.equal "GET" 57 | response["REQUEST_PATH"].should.equal "/test/foo" 58 | response["PATH_INFO"].should.equal "/test/foo" 59 | response["QUERY_STRING"].should.equal "quux=1" 60 | end 61 | 62 | specify "should have CGI headers on POST" do 63 | POST("/", {"rack-form-data" => "23"}, {'X-test-header' => '42'}) 64 | status.should.equal 200 65 | response["REQUEST_METHOD"].should.equal "POST" 66 | response["REQUEST_PATH"].should.equal "/" 67 | response["QUERY_STRING"].should.equal "" 68 | response["HTTP_X_TEST_HEADER"].should.equal "42" 69 | response["test.postdata"].should.equal "rack-form-data=23" 70 | end 71 | 72 | specify "should support HTTP auth" do 73 | GET("/test", {:user => "ruth", :passwd => "secret"}) 74 | response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ=" 75 | end 76 | 77 | specify "should set status" do 78 | GET("/test?secret") 79 | status.should.equal 403 80 | response["rack.url_scheme"].should.equal "http" 81 | end 82 | 83 | teardown do 84 | @server.stop! 85 | @thread.kill 86 | end 87 | end 88 | 89 | rescue LoadError 90 | $stderr.puts "Skipping Rack::Handler::Thin tests (Thin is required). `gem install thin` and try again." 91 | end 92 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_fastcgi.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | require 'testrequest' 3 | 4 | context "Rack::Handler::FastCGI" do 5 | include TestRequest::Helpers 6 | 7 | setup do 8 | @host = '0.0.0.0' 9 | @port = 9203 10 | end 11 | 12 | # Keep this first. 13 | specify "startup" do 14 | $pid = fork { 15 | Dir.chdir(File.join(File.dirname(__FILE__), "..", "test", "cgi")) 16 | exec "lighttpd -D -f lighttpd.conf" 17 | } 18 | end 19 | 20 | specify "should respond" do 21 | sleep 1 22 | lambda { 23 | GET("/test.fcgi") 24 | }.should.not.raise 25 | end 26 | 27 | specify "should be a lighttpd" do 28 | GET("/test.fcgi") 29 | status.should.be 200 30 | response["SERVER_SOFTWARE"].should =~ /lighttpd/ 31 | response["HTTP_VERSION"].should.equal "HTTP/1.1" 32 | response["SERVER_PROTOCOL"].should.equal "HTTP/1.1" 33 | response["SERVER_PORT"].should.equal @port.to_s 34 | response["SERVER_NAME"].should =~ @host 35 | end 36 | 37 | specify "should have rack headers" do 38 | GET("/test.fcgi") 39 | response["rack.version"].should.equal [1,1] 40 | response["rack.multithread"].should.be false 41 | response["rack.multiprocess"].should.be true 42 | response["rack.run_once"].should.be false 43 | end 44 | 45 | specify "should have CGI headers on GET" do 46 | GET("/test.fcgi") 47 | response["REQUEST_METHOD"].should.equal "GET" 48 | response["SCRIPT_NAME"].should.equal "/test.fcgi" 49 | response["REQUEST_PATH"].should.equal "/" 50 | response["PATH_INFO"].should.equal "" 51 | response["QUERY_STRING"].should.equal "" 52 | response["test.postdata"].should.equal "" 53 | 54 | GET("/test.fcgi/foo?quux=1") 55 | response["REQUEST_METHOD"].should.equal "GET" 56 | response["SCRIPT_NAME"].should.equal "/test.fcgi" 57 | response["REQUEST_PATH"].should.equal "/" 58 | response["PATH_INFO"].should.equal "/foo" 59 | response["QUERY_STRING"].should.equal "quux=1" 60 | end 61 | 62 | specify "should have CGI headers on POST" do 63 | POST("/test.fcgi", {"rack-form-data" => "23"}, {'X-test-header' => '42'}) 64 | status.should.equal 200 65 | response["REQUEST_METHOD"].should.equal "POST" 66 | response["SCRIPT_NAME"].should.equal "/test.fcgi" 67 | response["REQUEST_PATH"].should.equal "/" 68 | response["QUERY_STRING"].should.equal "" 69 | response["HTTP_X_TEST_HEADER"].should.equal "42" 70 | response["test.postdata"].should.equal "rack-form-data=23" 71 | end 72 | 73 | specify "should support HTTP auth" do 74 | GET("/test.fcgi", {:user => "ruth", :passwd => "secret"}) 75 | response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ=" 76 | end 77 | 78 | specify "should set status" do 79 | GET("/test.fcgi?secret") 80 | status.should.equal 403 81 | response["rack.url_scheme"].should.equal "http" 82 | end 83 | 84 | # Keep this last. 85 | specify "shutdown" do 86 | Process.kill 15, $pid 87 | Process.wait($pid).should.equal $pid 88 | end 89 | end 90 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/handler.rb: -------------------------------------------------------------------------------- 1 | module Rack 2 | # *Handlers* connect web servers with Rack. 3 | # 4 | # Rack includes Handlers for Mongrel, WEBrick, FastCGI, CGI, SCGI 5 | # and LiteSpeed. 6 | # 7 | # Handlers usually are activated by calling MyHandler.run(myapp). 8 | # A second optional hash can be passed to include server-specific 9 | # configuration. 10 | module Handler 11 | def self.get(server) 12 | return unless server 13 | server = server.to_s 14 | 15 | if klass = @handlers[server] 16 | obj = Object 17 | klass.split("::").each { |x| obj = obj.const_get(x) } 18 | obj 19 | else 20 | try_require('rack/handler', server) 21 | const_get(server) 22 | end 23 | end 24 | 25 | def self.default(options = {}) 26 | # Guess. 27 | if ENV.include?("PHP_FCGI_CHILDREN") 28 | # We already speak FastCGI 29 | options.delete :File 30 | options.delete :Port 31 | 32 | Rack::Handler::FastCGI 33 | elsif ENV.include?("REQUEST_METHOD") 34 | Rack::Handler::CGI 35 | else 36 | begin 37 | Rack::Handler::Mongrel 38 | rescue LoadError => e 39 | Rack::Handler::WEBrick 40 | end 41 | end 42 | end 43 | 44 | # Transforms server-name constants to their canonical form as filenames, 45 | # then tries to require them but silences the LoadError if not found 46 | # 47 | # Naming convention: 48 | # 49 | # Foo # => 'foo' 50 | # FooBar # => 'foo_bar.rb' 51 | # FooBAR # => 'foobar.rb' 52 | # FOObar # => 'foobar.rb' 53 | # FOOBAR # => 'foobar.rb' 54 | # FooBarBaz # => 'foo_bar_baz.rb' 55 | def self.try_require(prefix, const_name) 56 | file = const_name.gsub(/^[A-Z]+/) { |pre| pre.downcase }. 57 | gsub(/[A-Z]+[^A-Z]/, '_\&').downcase 58 | 59 | require(::File.join(prefix, file)) 60 | rescue LoadError 61 | end 62 | 63 | def self.register(server, klass) 64 | @handlers ||= {} 65 | @handlers[server] = klass 66 | end 67 | 68 | autoload :CGI, "rack/handler/cgi" 69 | autoload :FastCGI, "rack/handler/fastcgi" 70 | autoload :Mongrel, "rack/handler/mongrel" 71 | autoload :EventedMongrel, "rack/handler/evented_mongrel" 72 | autoload :SwiftipliedMongrel, "rack/handler/swiftiplied_mongrel" 73 | autoload :WEBrick, "rack/handler/webrick" 74 | autoload :LSWS, "rack/handler/lsws" 75 | autoload :SCGI, "rack/handler/scgi" 76 | autoload :Thin, "rack/handler/thin" 77 | 78 | register 'cgi', 'Rack::Handler::CGI' 79 | register 'fastcgi', 'Rack::Handler::FastCGI' 80 | register 'mongrel', 'Rack::Handler::Mongrel' 81 | register 'emongrel', 'Rack::Handler::EventedMongrel' 82 | register 'smongrel', 'Rack::Handler::SwiftipliedMongrel' 83 | register 'webrick', 'Rack::Handler::WEBrick' 84 | register 'lsws', 'Rack::Handler::LSWS' 85 | register 'scgi', 'Rack::Handler::SCGI' 86 | register 'thin', 'Rack::Handler::Thin' 87 | end 88 | end 89 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/sinatra.gemspec: -------------------------------------------------------------------------------- 1 | Gem::Specification.new do |s| 2 | s.specification_version = 2 if s.respond_to? :specification_version= 3 | s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= 4 | 5 | s.name = 'sinatra' 6 | s.version = '1.0' 7 | s.date = '2010-03-23' 8 | 9 | s.description = "Classy web-development dressed in a DSL" 10 | s.summary = "Classy web-development dressed in a DSL" 11 | 12 | s.authors = ["Blake Mizerany", "Ryan Tomayko", "Simon Rozet"] 13 | s.email = "sinatrarb@googlegroups.com" 14 | 15 | # = MANIFEST = 16 | s.files = %w[ 17 | AUTHORS 18 | CHANGES 19 | LICENSE 20 | README.jp.rdoc 21 | README.rdoc 22 | Rakefile 23 | lib/sinatra.rb 24 | lib/sinatra/base.rb 25 | lib/sinatra/images/404.png 26 | lib/sinatra/images/500.png 27 | lib/sinatra/main.rb 28 | lib/sinatra/showexceptions.rb 29 | lib/sinatra/tilt.rb 30 | sinatra.gemspec 31 | test/base_test.rb 32 | test/builder_test.rb 33 | test/contest.rb 34 | test/erb_test.rb 35 | test/erubis_test.rb 36 | test/extensions_test.rb 37 | test/filter_test.rb 38 | test/haml_test.rb 39 | test/helper.rb 40 | test/helpers_test.rb 41 | test/less_test.rb 42 | test/mapped_error_test.rb 43 | test/middleware_test.rb 44 | test/public/favicon.ico 45 | test/request_test.rb 46 | test/response_test.rb 47 | test/result_test.rb 48 | test/route_added_hook_test.rb 49 | test/routing_test.rb 50 | test/sass_test.rb 51 | test/server_test.rb 52 | test/settings_test.rb 53 | test/sinatra_test.rb 54 | test/static_test.rb 55 | test/templates_test.rb 56 | test/views/error.builder 57 | test/views/error.erb 58 | test/views/error.erubis 59 | test/views/error.haml 60 | test/views/error.sass 61 | test/views/foo/hello.test 62 | test/views/hello.builder 63 | test/views/hello.erb 64 | test/views/hello.erubis 65 | test/views/hello.haml 66 | test/views/hello.less 67 | test/views/hello.sass 68 | test/views/hello.test 69 | test/views/layout2.builder 70 | test/views/layout2.erb 71 | test/views/layout2.erubis 72 | test/views/layout2.haml 73 | test/views/layout2.test 74 | ] 75 | # = MANIFEST = 76 | 77 | s.test_files = s.files.select {|path| path =~ /^test\/.*_test.rb/} 78 | 79 | s.extra_rdoc_files = %w[README.rdoc LICENSE] 80 | s.add_dependency 'rack', '>= 1.0' 81 | s.add_development_dependency 'shotgun', '>= 0.6', '< 1.0' 82 | s.add_development_dependency 'rack-test', '>= 0.3.0' 83 | s.add_development_dependency 'haml' 84 | s.add_development_dependency 'builder' 85 | s.add_development_dependency 'erubis' 86 | s.add_development_dependency 'less' 87 | 88 | s.has_rdoc = true 89 | s.homepage = "http://sinatra.rubyforge.org" 90 | s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Sinatra", "--main", "README.rdoc"] 91 | s.require_paths = %w[lib] 92 | s.rubyforge_project = 'sinatra' 93 | s.rubygems_version = '1.1.1' 94 | end 95 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_session_cookie.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | 3 | require 'rack/session/cookie' 4 | require 'rack/mock' 5 | require 'rack/response' 6 | 7 | context "Rack::Session::Cookie" do 8 | incrementor = lambda { |env| 9 | env["rack.session"]["counter"] ||= 0 10 | env["rack.session"]["counter"] += 1 11 | Rack::Response.new(env["rack.session"].inspect).to_a 12 | } 13 | 14 | specify "creates a new cookie" do 15 | res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor)).get("/") 16 | res["Set-Cookie"].should.match("rack.session=") 17 | res.body.should.equal '{"counter"=>1}' 18 | end 19 | 20 | specify "loads from a cookie" do 21 | res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor)).get("/") 22 | cookie = res["Set-Cookie"] 23 | res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor)). 24 | get("/", "HTTP_COOKIE" => cookie) 25 | res.body.should.equal '{"counter"=>2}' 26 | cookie = res["Set-Cookie"] 27 | res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor)). 28 | get("/", "HTTP_COOKIE" => cookie) 29 | res.body.should.equal '{"counter"=>3}' 30 | end 31 | 32 | specify "survives broken cookies" do 33 | res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor)). 34 | get("/", "HTTP_COOKIE" => "rack.session=blarghfasel") 35 | res.body.should.equal '{"counter"=>1}' 36 | end 37 | 38 | bigcookie = lambda { |env| 39 | env["rack.session"]["cookie"] = "big" * 3000 40 | Rack::Response.new(env["rack.session"].inspect).to_a 41 | } 42 | 43 | specify "barks on too big cookies" do 44 | lambda { 45 | Rack::MockRequest.new(Rack::Session::Cookie.new(bigcookie)). 46 | get("/", :fatal => true) 47 | }.should.raise(Rack::MockRequest::FatalWarning) 48 | end 49 | 50 | specify "loads from a cookie wih integrity hash" do 51 | res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor, :secret => 'test')).get("/") 52 | cookie = res["Set-Cookie"] 53 | res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor, :secret => 'test')). 54 | get("/", "HTTP_COOKIE" => cookie) 55 | res.body.should.equal '{"counter"=>2}' 56 | cookie = res["Set-Cookie"] 57 | res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor, :secret => 'test')). 58 | get("/", "HTTP_COOKIE" => cookie) 59 | res.body.should.equal '{"counter"=>3}' 60 | end 61 | 62 | specify "ignores tampered with session cookies" do 63 | app = Rack::Session::Cookie.new(incrementor, :secret => 'test') 64 | response1 = Rack::MockRequest.new(app).get("/") 65 | _, digest = response1["Set-Cookie"].split("--") 66 | tampered_with_cookie = "hackerman-was-here" + "--" + digest 67 | response2 = Rack::MockRequest.new(app).get("/", "HTTP_COOKIE" => 68 | tampered_with_cookie) 69 | 70 | # The tampered-with cookie is ignored, so we get back an identical Set-Cookie 71 | response2["Set-Cookie"].should.equal(response1["Set-Cookie"]) 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/static_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/helper' 2 | 3 | class StaticTest < Test::Unit::TestCase 4 | setup do 5 | mock_app { 6 | set :static, true 7 | set :public, File.dirname(__FILE__) 8 | } 9 | end 10 | 11 | it 'serves GET requests for files in the public directory' do 12 | get "/#{File.basename(__FILE__)}" 13 | assert ok? 14 | assert_equal File.read(__FILE__), body 15 | assert_equal File.size(__FILE__).to_s, response['Content-Length'] 16 | assert response.headers.include?('Last-Modified') 17 | end 18 | 19 | it 'produces a body that can be iterated over multiple times' do 20 | env = Rack::MockRequest.env_for("/#{File.basename(__FILE__)}") 21 | status, headers, body = @app.call(env) 22 | buf1, buf2 = [], [] 23 | body.each { |part| buf1 << part } 24 | body.each { |part| buf2 << part } 25 | assert_equal buf1.join, buf2.join 26 | assert_equal File.read(__FILE__), buf1.join 27 | end 28 | 29 | it 'sets the sinatra.static_file env variable if served' do 30 | env = Rack::MockRequest.env_for("/#{File.basename(__FILE__)}") 31 | status, headers, body = @app.call(env) 32 | assert_equal File.expand_path(__FILE__), env['sinatra.static_file'] 33 | end 34 | 35 | it 'serves HEAD requests for files in the public directory' do 36 | head "/#{File.basename(__FILE__)}" 37 | assert ok? 38 | assert_equal '', body 39 | assert_equal File.size(__FILE__).to_s, response['Content-Length'] 40 | assert response.headers.include?('Last-Modified') 41 | end 42 | 43 | %w[POST PUT DELETE].each do |verb| 44 | it "does not serve #{verb} requests" do 45 | send verb.downcase, "/#{File.basename(__FILE__)}" 46 | assert_equal 404, status 47 | end 48 | end 49 | 50 | it 'serves files in preference to custom routes' do 51 | @app.get("/#{File.basename(__FILE__)}") { 'Hello World' } 52 | get "/#{File.basename(__FILE__)}" 53 | assert ok? 54 | assert body != 'Hello World' 55 | end 56 | 57 | it 'does not serve directories' do 58 | get "/" 59 | assert not_found? 60 | end 61 | 62 | it 'passes to the next handler when the static option is disabled' do 63 | @app.set :static, false 64 | get "/#{File.basename(__FILE__)}" 65 | assert not_found? 66 | end 67 | 68 | it 'passes to the next handler when the public option is nil' do 69 | @app.set :public, nil 70 | get "/#{File.basename(__FILE__)}" 71 | assert not_found? 72 | end 73 | 74 | it '404s when a file is not found' do 75 | get "/foobarbaz.txt" 76 | assert not_found? 77 | end 78 | 79 | it 'serves files when .. path traverses within public directory' do 80 | get "/data/../#{File.basename(__FILE__)}" 81 | assert ok? 82 | assert_equal File.read(__FILE__), body 83 | end 84 | 85 | it '404s when .. path traverses outside of public directory' do 86 | mock_app { 87 | set :static, true 88 | set :public, File.dirname(__FILE__) + '/data' 89 | } 90 | get "/../#{File.basename(__FILE__)}" 91 | assert not_found? 92 | end 93 | end 94 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/session/cookie.rb: -------------------------------------------------------------------------------- 1 | require 'openssl' 2 | require 'rack/request' 3 | require 'rack/response' 4 | 5 | module Rack 6 | 7 | module Session 8 | 9 | # Rack::Session::Cookie provides simple cookie based session management. 10 | # The session is a Ruby Hash stored as base64 encoded marshalled data 11 | # set to :key (default: rack.session). 12 | # When the secret key is set, cookie data is checked for data integrity. 13 | # 14 | # Example: 15 | # 16 | # use Rack::Session::Cookie, :key => 'rack.session', 17 | # :domain => 'foo.com', 18 | # :path => '/', 19 | # :expire_after => 2592000, 20 | # :secret => 'change_me' 21 | # 22 | # All parameters are optional. 23 | 24 | class Cookie 25 | 26 | def initialize(app, options={}) 27 | @app = app 28 | @key = options[:key] || "rack.session" 29 | @secret = options[:secret] 30 | @default_options = {:domain => nil, 31 | :path => "/", 32 | :expire_after => nil}.merge(options) 33 | end 34 | 35 | def call(env) 36 | load_session(env) 37 | status, headers, body = @app.call(env) 38 | commit_session(env, status, headers, body) 39 | end 40 | 41 | private 42 | 43 | def load_session(env) 44 | request = Rack::Request.new(env) 45 | session_data = request.cookies[@key] 46 | 47 | if @secret && session_data 48 | session_data, digest = session_data.split("--") 49 | session_data = nil unless digest == generate_hmac(session_data) 50 | end 51 | 52 | begin 53 | session_data = session_data.unpack("m*").first 54 | session_data = Marshal.load(session_data) 55 | env["rack.session"] = session_data 56 | rescue 57 | env["rack.session"] = Hash.new 58 | end 59 | 60 | env["rack.session.options"] = @default_options.dup 61 | end 62 | 63 | def commit_session(env, status, headers, body) 64 | session_data = Marshal.dump(env["rack.session"]) 65 | session_data = [session_data].pack("m*") 66 | 67 | if @secret 68 | session_data = "#{session_data}--#{generate_hmac(session_data)}" 69 | end 70 | 71 | if session_data.size > (4096 - @key.size) 72 | env["rack.errors"].puts("Warning! Rack::Session::Cookie data size exceeds 4K. Content dropped.") 73 | else 74 | options = env["rack.session.options"] 75 | cookie = Hash.new 76 | cookie[:value] = session_data 77 | cookie[:expires] = Time.now + options[:expire_after] unless options[:expire_after].nil? 78 | Utils.set_cookie_header!(headers, @key, cookie.merge(options)) 79 | end 80 | 81 | [status, headers, body] 82 | end 83 | 84 | def generate_hmac(data) 85 | OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, @secret, data) 86 | end 87 | 88 | end 89 | end 90 | end 91 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/deflater.rb: -------------------------------------------------------------------------------- 1 | require "zlib" 2 | require "stringio" 3 | require "time" # for Time.httpdate 4 | require 'rack/utils' 5 | 6 | module Rack 7 | class Deflater 8 | def initialize(app) 9 | @app = app 10 | end 11 | 12 | def call(env) 13 | status, headers, body = @app.call(env) 14 | headers = Utils::HeaderHash.new(headers) 15 | 16 | # Skip compressing empty entity body responses and responses with 17 | # no-transform set. 18 | if Utils::STATUS_WITH_NO_ENTITY_BODY.include?(status) || 19 | headers['Cache-Control'].to_s =~ /\bno-transform\b/ 20 | return [status, headers, body] 21 | end 22 | 23 | request = Request.new(env) 24 | 25 | encoding = Utils.select_best_encoding(%w(gzip deflate identity), 26 | request.accept_encoding) 27 | 28 | # Set the Vary HTTP header. 29 | vary = headers["Vary"].to_s.split(",").map { |v| v.strip } 30 | unless vary.include?("*") || vary.include?("Accept-Encoding") 31 | headers["Vary"] = vary.push("Accept-Encoding").join(",") 32 | end 33 | 34 | case encoding 35 | when "gzip" 36 | headers['Content-Encoding'] = "gzip" 37 | headers.delete('Content-Length') 38 | mtime = headers.key?("Last-Modified") ? 39 | Time.httpdate(headers["Last-Modified"]) : Time.now 40 | [status, headers, GzipStream.new(body, mtime)] 41 | when "deflate" 42 | headers['Content-Encoding'] = "deflate" 43 | headers.delete('Content-Length') 44 | [status, headers, DeflateStream.new(body)] 45 | when "identity" 46 | [status, headers, body] 47 | when nil 48 | message = "An acceptable encoding for the requested resource #{request.fullpath} could not be found." 49 | [406, {"Content-Type" => "text/plain", "Content-Length" => message.length.to_s}, [message]] 50 | end 51 | end 52 | 53 | class GzipStream 54 | def initialize(body, mtime) 55 | @body = body 56 | @mtime = mtime 57 | end 58 | 59 | def each(&block) 60 | @writer = block 61 | gzip =::Zlib::GzipWriter.new(self) 62 | gzip.mtime = @mtime 63 | @body.each { |part| gzip.write(part) } 64 | @body.close if @body.respond_to?(:close) 65 | gzip.close 66 | @writer = nil 67 | end 68 | 69 | def write(data) 70 | @writer.call(data) 71 | end 72 | end 73 | 74 | class DeflateStream 75 | DEFLATE_ARGS = [ 76 | Zlib::DEFAULT_COMPRESSION, 77 | # drop the zlib header which causes both Safari and IE to choke 78 | -Zlib::MAX_WBITS, 79 | Zlib::DEF_MEM_LEVEL, 80 | Zlib::DEFAULT_STRATEGY 81 | ] 82 | 83 | def initialize(body) 84 | @body = body 85 | end 86 | 87 | def each 88 | deflater = ::Zlib::Deflate.new(*DEFLATE_ARGS) 89 | @body.each { |part| yield deflater.deflate(part) } 90 | @body.close if @body.respond_to?(:close) 91 | yield deflater.finish 92 | nil 93 | end 94 | end 95 | end 96 | end 97 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/handler/mongrel.rb: -------------------------------------------------------------------------------- 1 | require 'mongrel' 2 | require 'stringio' 3 | require 'rack/content_length' 4 | require 'rack/chunked' 5 | 6 | module Rack 7 | module Handler 8 | class Mongrel < ::Mongrel::HttpHandler 9 | def self.run(app, options={}) 10 | server = ::Mongrel::HttpServer.new( 11 | options[:Host] || '0.0.0.0', 12 | options[:Port] || 8080, 13 | options[:num_processors] || 950, 14 | options[:throttle] || 0, 15 | options[:timeout] || 60) 16 | # Acts like Rack::URLMap, utilizing Mongrel's own path finding methods. 17 | # Use is similar to #run, replacing the app argument with a hash of 18 | # { path=>app, ... } or an instance of Rack::URLMap. 19 | if options[:map] 20 | if app.is_a? Hash 21 | app.each do |path, appl| 22 | path = '/'+path unless path[0] == ?/ 23 | server.register(path, Rack::Handler::Mongrel.new(appl)) 24 | end 25 | elsif app.is_a? URLMap 26 | app.instance_variable_get(:@mapping).each do |(host, path, appl)| 27 | next if !host.nil? && !options[:Host].nil? && options[:Host] != host 28 | path = '/'+path unless path[0] == ?/ 29 | server.register(path, Rack::Handler::Mongrel.new(appl)) 30 | end 31 | else 32 | raise ArgumentError, "first argument should be a Hash or URLMap" 33 | end 34 | else 35 | server.register('/', Rack::Handler::Mongrel.new(app)) 36 | end 37 | yield server if block_given? 38 | server.run.join 39 | end 40 | 41 | def initialize(app) 42 | @app = Rack::Chunked.new(Rack::ContentLength.new(app)) 43 | end 44 | 45 | def process(request, response) 46 | env = {}.replace(request.params) 47 | env.delete "HTTP_CONTENT_TYPE" 48 | env.delete "HTTP_CONTENT_LENGTH" 49 | 50 | env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/" 51 | 52 | rack_input = request.body || StringIO.new('') 53 | rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding) 54 | 55 | env.update({"rack.version" => [1,1], 56 | "rack.input" => rack_input, 57 | "rack.errors" => $stderr, 58 | 59 | "rack.multithread" => true, 60 | "rack.multiprocess" => false, # ??? 61 | "rack.run_once" => false, 62 | 63 | "rack.url_scheme" => "http", 64 | }) 65 | env["QUERY_STRING"] ||= "" 66 | 67 | status, headers, body = @app.call(env) 68 | 69 | begin 70 | response.status = status.to_i 71 | response.send_status(nil) 72 | 73 | headers.each { |k, vs| 74 | vs.split("\n").each { |v| 75 | response.header[k] = v 76 | } 77 | } 78 | response.send_header 79 | 80 | body.each { |part| 81 | response.write part 82 | response.socket.flush 83 | } 84 | ensure 85 | body.close if body.respond_to? :close 86 | end 87 | end 88 | end 89 | end 90 | end 91 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/extensions_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/helper' 2 | 3 | class ExtensionsTest < Test::Unit::TestCase 4 | module FooExtensions 5 | def foo 6 | end 7 | 8 | private 9 | def im_hiding_in_ur_foos 10 | end 11 | end 12 | 13 | module BarExtensions 14 | def bar 15 | end 16 | end 17 | 18 | module BazExtensions 19 | def baz 20 | end 21 | end 22 | 23 | module QuuxExtensions 24 | def quux 25 | end 26 | end 27 | 28 | module PainExtensions 29 | def foo=(name); end 30 | def bar?(name); end 31 | def fizz!(name); end 32 | end 33 | 34 | it 'will add the methods to the DSL for the class in which you register them and its subclasses' do 35 | Sinatra::Base.register FooExtensions 36 | assert Sinatra::Base.respond_to?(:foo) 37 | 38 | Sinatra::Application.register BarExtensions 39 | assert Sinatra::Application.respond_to?(:bar) 40 | assert Sinatra::Application.respond_to?(:foo) 41 | assert !Sinatra::Base.respond_to?(:bar) 42 | end 43 | 44 | it 'allows extending by passing a block' do 45 | Sinatra::Base.register { 46 | def im_in_ur_anonymous_module; end 47 | } 48 | assert Sinatra::Base.respond_to?(:im_in_ur_anonymous_module) 49 | end 50 | 51 | it 'will make sure any public methods added via Application#register are delegated to Sinatra::Delegator' do 52 | Sinatra::Application.register FooExtensions 53 | assert Sinatra::Delegator.private_instance_methods. 54 | map { |m| m.to_sym }.include?(:foo) 55 | assert !Sinatra::Delegator.private_instance_methods. 56 | map { |m| m.to_sym }.include?(:im_hiding_in_ur_foos) 57 | end 58 | 59 | it 'will handle special method names' do 60 | Sinatra::Application.register PainExtensions 61 | assert Sinatra::Delegator.private_instance_methods. 62 | map { |m| m.to_sym }.include?(:foo=) 63 | assert Sinatra::Delegator.private_instance_methods. 64 | map { |m| m.to_sym }.include?(:bar?) 65 | assert Sinatra::Delegator.private_instance_methods. 66 | map { |m| m.to_sym }.include?(:fizz!) 67 | end 68 | 69 | it 'will not delegate methods on Base#register' do 70 | Sinatra::Base.register QuuxExtensions 71 | assert !Sinatra::Delegator.private_instance_methods.include?("quux") 72 | end 73 | 74 | it 'will extend the Sinatra::Application application by default' do 75 | Sinatra.register BazExtensions 76 | assert !Sinatra::Base.respond_to?(:baz) 77 | assert Sinatra::Application.respond_to?(:baz) 78 | end 79 | 80 | module BizzleExtension 81 | def bizzle 82 | bizzle_option 83 | end 84 | 85 | def self.registered(base) 86 | fail "base should be BizzleApp" unless base == BizzleApp 87 | fail "base should have already extended BizzleExtension" unless base.respond_to?(:bizzle) 88 | base.set :bizzle_option, 'bizzle!' 89 | end 90 | end 91 | 92 | class BizzleApp < Sinatra::Base 93 | end 94 | 95 | it 'sends .registered to the extension module after extending the class' do 96 | BizzleApp.register BizzleExtension 97 | assert_equal 'bizzle!', BizzleApp.bizzle_option 98 | assert_equal 'bizzle!', BizzleApp.bizzle 99 | end 100 | end 101 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack.rb: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2007, 2008, 2009, 2010 Christian Neukirchen 2 | # 3 | # Rack is freely distributable under the terms of an MIT-style license. 4 | # See COPYING or http://www.opensource.org/licenses/mit-license.php. 5 | 6 | # The Rack main module, serving as a namespace for all core Rack 7 | # modules and classes. 8 | # 9 | # All modules meant for use in your application are autoloaded here, 10 | # so it should be enough just to require rack.rb in your code. 11 | 12 | module Rack 13 | # The Rack protocol version number implemented. 14 | VERSION = [1,1] 15 | 16 | # Return the Rack protocol version as a dotted string. 17 | def self.version 18 | VERSION.join(".") 19 | end 20 | 21 | # Return the Rack release as a dotted string. 22 | def self.release 23 | "1.1" 24 | end 25 | 26 | autoload :Builder, "rack/builder" 27 | autoload :Cascade, "rack/cascade" 28 | autoload :Chunked, "rack/chunked" 29 | autoload :CommonLogger, "rack/commonlogger" 30 | autoload :ConditionalGet, "rack/conditionalget" 31 | autoload :Config, "rack/config" 32 | autoload :ContentLength, "rack/content_length" 33 | autoload :ContentType, "rack/content_type" 34 | autoload :ETag, "rack/etag" 35 | autoload :File, "rack/file" 36 | autoload :Deflater, "rack/deflater" 37 | autoload :Directory, "rack/directory" 38 | autoload :ForwardRequest, "rack/recursive" 39 | autoload :Handler, "rack/handler" 40 | autoload :Head, "rack/head" 41 | autoload :Lint, "rack/lint" 42 | autoload :Lock, "rack/lock" 43 | autoload :Logger, "rack/logger" 44 | autoload :MethodOverride, "rack/methodoverride" 45 | autoload :Mime, "rack/mime" 46 | autoload :NullLogger, "rack/nulllogger" 47 | autoload :Recursive, "rack/recursive" 48 | autoload :Reloader, "rack/reloader" 49 | autoload :Runtime, "rack/runtime" 50 | autoload :Sendfile, "rack/sendfile" 51 | autoload :Server, "rack/server" 52 | autoload :ShowExceptions, "rack/showexceptions" 53 | autoload :ShowStatus, "rack/showstatus" 54 | autoload :Static, "rack/static" 55 | autoload :URLMap, "rack/urlmap" 56 | autoload :Utils, "rack/utils" 57 | 58 | autoload :MockRequest, "rack/mock" 59 | autoload :MockResponse, "rack/mock" 60 | 61 | autoload :Request, "rack/request" 62 | autoload :Response, "rack/response" 63 | 64 | module Auth 65 | autoload :Basic, "rack/auth/basic" 66 | autoload :AbstractRequest, "rack/auth/abstract/request" 67 | autoload :AbstractHandler, "rack/auth/abstract/handler" 68 | module Digest 69 | autoload :MD5, "rack/auth/digest/md5" 70 | autoload :Nonce, "rack/auth/digest/nonce" 71 | autoload :Params, "rack/auth/digest/params" 72 | autoload :Request, "rack/auth/digest/request" 73 | end 74 | end 75 | 76 | module Session 77 | autoload :Cookie, "rack/session/cookie" 78 | autoload :Pool, "rack/session/pool" 79 | autoload :Memcache, "rack/session/memcache" 80 | end 81 | 82 | # *Adapters* connect Rack with third party web frameworks. 83 | # 84 | # Rack includes an adapter for Camping, see README for other 85 | # frameworks supporting Rack in their code bases. 86 | # 87 | # Refer to the submodules for framework-specific calling details. 88 | 89 | module Adapter 90 | autoload :Camping, "rack/adapter/camping" 91 | end 92 | end 93 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/auth/digest/md5.rb: -------------------------------------------------------------------------------- 1 | require 'rack/auth/abstract/handler' 2 | require 'rack/auth/digest/request' 3 | require 'rack/auth/digest/params' 4 | require 'rack/auth/digest/nonce' 5 | require 'digest/md5' 6 | 7 | module Rack 8 | module Auth 9 | module Digest 10 | # Rack::Auth::Digest::MD5 implements the MD5 algorithm version of 11 | # HTTP Digest Authentication, as per RFC 2617. 12 | # 13 | # Initialize with the [Rack] application that you want protecting, 14 | # and a block that looks up a plaintext password for a given username. 15 | # 16 | # +opaque+ needs to be set to a constant base64/hexadecimal string. 17 | # 18 | class MD5 < AbstractHandler 19 | 20 | attr_accessor :opaque 21 | 22 | attr_writer :passwords_hashed 23 | 24 | def initialize(*args) 25 | super 26 | @passwords_hashed = nil 27 | end 28 | 29 | def passwords_hashed? 30 | !!@passwords_hashed 31 | end 32 | 33 | def call(env) 34 | auth = Request.new(env) 35 | 36 | unless auth.provided? 37 | return unauthorized 38 | end 39 | 40 | if !auth.digest? || !auth.correct_uri? || !valid_qop?(auth) 41 | return bad_request 42 | end 43 | 44 | if valid?(auth) 45 | if auth.nonce.stale? 46 | return unauthorized(challenge(:stale => true)) 47 | else 48 | env['REMOTE_USER'] = auth.username 49 | 50 | return @app.call(env) 51 | end 52 | end 53 | 54 | unauthorized 55 | end 56 | 57 | 58 | private 59 | 60 | QOP = 'auth'.freeze 61 | 62 | def params(hash = {}) 63 | Params.new do |params| 64 | params['realm'] = realm 65 | params['nonce'] = Nonce.new.to_s 66 | params['opaque'] = H(opaque) 67 | params['qop'] = QOP 68 | 69 | hash.each { |k, v| params[k] = v } 70 | end 71 | end 72 | 73 | def challenge(hash = {}) 74 | "Digest #{params(hash)}" 75 | end 76 | 77 | def valid?(auth) 78 | valid_opaque?(auth) && valid_nonce?(auth) && valid_digest?(auth) 79 | end 80 | 81 | def valid_qop?(auth) 82 | QOP == auth.qop 83 | end 84 | 85 | def valid_opaque?(auth) 86 | H(opaque) == auth.opaque 87 | end 88 | 89 | def valid_nonce?(auth) 90 | auth.nonce.valid? 91 | end 92 | 93 | def valid_digest?(auth) 94 | digest(auth, @authenticator.call(auth.username)) == auth.response 95 | end 96 | 97 | def md5(data) 98 | ::Digest::MD5.hexdigest(data) 99 | end 100 | 101 | alias :H :md5 102 | 103 | def KD(secret, data) 104 | H([secret, data] * ':') 105 | end 106 | 107 | def A1(auth, password) 108 | [ auth.username, auth.realm, password ] * ':' 109 | end 110 | 111 | def A2(auth) 112 | [ auth.method, auth.uri ] * ':' 113 | end 114 | 115 | def digest(auth, password) 116 | password_hash = passwords_hashed? ? password : H(A1(auth, password)) 117 | 118 | KD(password_hash, [ auth.nonce, auth.nc, auth.cnonce, QOP, H(A2(auth)) ] * ':') 119 | end 120 | 121 | end 122 | end 123 | end 124 | end 125 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/reloader.rb: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009 Michael Fellinger m.fellinger@gmail.com 2 | # Rack::Reloader is subject to the terms of an MIT-style license. 3 | # See COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | require 'pathname' 6 | 7 | module Rack 8 | 9 | # High performant source reloader 10 | # 11 | # This class acts as Rack middleware. 12 | # 13 | # What makes it especially suited for use in a production environment is that 14 | # any file will only be checked once and there will only be made one system 15 | # call stat(2). 16 | # 17 | # Please note that this will not reload files in the background, it does so 18 | # only when actively called. 19 | # 20 | # It is performing a check/reload cycle at the start of every request, but 21 | # also respects a cool down time, during which nothing will be done. 22 | class Reloader 23 | def initialize(app, cooldown = 10, backend = Stat) 24 | @app = app 25 | @cooldown = cooldown 26 | @last = (Time.now - cooldown) 27 | @cache = {} 28 | @mtimes = {} 29 | 30 | extend backend 31 | end 32 | 33 | def call(env) 34 | if @cooldown and Time.now > @last + @cooldown 35 | if Thread.list.size > 1 36 | Thread.exclusive{ reload! } 37 | else 38 | reload! 39 | end 40 | 41 | @last = Time.now 42 | end 43 | 44 | @app.call(env) 45 | end 46 | 47 | def reload!(stderr = $stderr) 48 | rotation do |file, mtime| 49 | previous_mtime = @mtimes[file] ||= mtime 50 | safe_load(file, mtime, stderr) if mtime > previous_mtime 51 | end 52 | end 53 | 54 | # A safe Kernel::load, issuing the hooks depending on the results 55 | def safe_load(file, mtime, stderr = $stderr) 56 | load(file) 57 | stderr.puts "#{self.class}: reloaded `#{file}'" 58 | file 59 | rescue LoadError, SyntaxError => ex 60 | stderr.puts ex 61 | ensure 62 | @mtimes[file] = mtime 63 | end 64 | 65 | module Stat 66 | def rotation 67 | files = [$0, *$LOADED_FEATURES].uniq 68 | paths = ['./', *$LOAD_PATH].uniq 69 | 70 | files.map{|file| 71 | next if file =~ /\.(so|bundle)$/ # cannot reload compiled files 72 | 73 | found, stat = figure_path(file, paths) 74 | next unless found && stat && mtime = stat.mtime 75 | 76 | @cache[file] = found 77 | 78 | yield(found, mtime) 79 | }.compact 80 | end 81 | 82 | # Takes a relative or absolute +file+ name, a couple possible +paths+ that 83 | # the +file+ might reside in. Returns the full path and File::Stat for the 84 | # path. 85 | def figure_path(file, paths) 86 | found = @cache[file] 87 | found = file if !found and Pathname.new(file).absolute? 88 | found, stat = safe_stat(found) 89 | return found, stat if found 90 | 91 | paths.find do |possible_path| 92 | path = ::File.join(possible_path, file) 93 | found, stat = safe_stat(path) 94 | return ::File.expand_path(found), stat if found 95 | end 96 | 97 | return false, false 98 | end 99 | 100 | def safe_stat(file) 101 | return unless file 102 | stat = ::File.stat(file) 103 | return file, stat if stat.file? 104 | rescue Errno::ENOENT, Errno::ENOTDIR 105 | @cache.delete(file) and false 106 | end 107 | end 108 | end 109 | end 110 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/rewindable_input.rb: -------------------------------------------------------------------------------- 1 | require 'tempfile' 2 | 3 | module Rack 4 | # Class which can make any IO object rewindable, including non-rewindable ones. It does 5 | # this by buffering the data into a tempfile, which is rewindable. 6 | # 7 | # rack.input is required to be rewindable, so if your input stream IO is non-rewindable 8 | # by nature (e.g. a pipe or a socket) then you can wrap it in an object of this class 9 | # to easily make it rewindable. 10 | # 11 | # Don't forget to call #close when you're done. This frees up temporary resources that 12 | # RewindableInput uses, though it does *not* close the original IO object. 13 | class RewindableInput 14 | def initialize(io) 15 | @io = io 16 | @rewindable_io = nil 17 | @unlinked = false 18 | end 19 | 20 | def gets 21 | make_rewindable unless @rewindable_io 22 | @rewindable_io.gets 23 | end 24 | 25 | def read(*args) 26 | make_rewindable unless @rewindable_io 27 | @rewindable_io.read(*args) 28 | end 29 | 30 | def each(&block) 31 | make_rewindable unless @rewindable_io 32 | @rewindable_io.each(&block) 33 | end 34 | 35 | def rewind 36 | make_rewindable unless @rewindable_io 37 | @rewindable_io.rewind 38 | end 39 | 40 | # Closes this RewindableInput object without closing the originally 41 | # wrapped IO oject. Cleans up any temporary resources that this RewindableInput 42 | # has created. 43 | # 44 | # This method may be called multiple times. It does nothing on subsequent calls. 45 | def close 46 | if @rewindable_io 47 | if @unlinked 48 | @rewindable_io.close 49 | else 50 | @rewindable_io.close! 51 | end 52 | @rewindable_io = nil 53 | end 54 | end 55 | 56 | private 57 | 58 | # Ruby's Tempfile class has a bug. Subclass it and fix it. 59 | class Tempfile < ::Tempfile 60 | def _close 61 | @tmpfile.close if @tmpfile 62 | @data[1] = nil if @data 63 | @tmpfile = nil 64 | end 65 | end 66 | 67 | def make_rewindable 68 | # Buffer all data into a tempfile. Since this tempfile is private to this 69 | # RewindableInput object, we chmod it so that nobody else can read or write 70 | # it. On POSIX filesystems we also unlink the file so that it doesn't 71 | # even have a file entry on the filesystem anymore, though we can still 72 | # access it because we have the file handle open. 73 | @rewindable_io = Tempfile.new('RackRewindableInput') 74 | @rewindable_io.chmod(0000) 75 | @rewindable_io.set_encoding(Encoding::BINARY) if @rewindable_io.respond_to?(:set_encoding) 76 | @rewindable_io.binmode 77 | if filesystem_has_posix_semantics? 78 | @rewindable_io.unlink 79 | @unlinked = true 80 | end 81 | 82 | buffer = "" 83 | while @io.read(1024 * 4, buffer) 84 | entire_buffer_written_out = false 85 | while !entire_buffer_written_out 86 | written = @rewindable_io.write(buffer) 87 | entire_buffer_written_out = written == buffer.size 88 | if !entire_buffer_written_out 89 | buffer.slice!(0 .. written - 1) 90 | end 91 | end 92 | end 93 | @rewindable_io.rewind 94 | end 95 | 96 | def filesystem_has_posix_semantics? 97 | RUBY_PLATFORM !~ /(mswin|mingw|cygwin|java)/ 98 | end 99 | end 100 | end 101 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_rewindable_input.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | require 'stringio' 3 | require 'rack/rewindable_input' 4 | 5 | shared_context "a rewindable IO object" do 6 | setup do 7 | @rio = Rack::RewindableInput.new(@io) 8 | end 9 | 10 | teardown do 11 | @rio.close 12 | end 13 | 14 | specify "should be able to handle to read()" do 15 | @rio.read.should.equal "hello world" 16 | end 17 | 18 | specify "should be able to handle to read(nil)" do 19 | @rio.read(nil).should.equal "hello world" 20 | end 21 | 22 | specify "should be able to handle to read(length)" do 23 | @rio.read(1).should.equal "h" 24 | end 25 | 26 | specify "should be able to handle to read(length, buffer)" do 27 | buffer = "" 28 | result = @rio.read(1, buffer) 29 | result.should.equal "h" 30 | result.object_id.should.equal buffer.object_id 31 | end 32 | 33 | specify "should be able to handle to read(nil, buffer)" do 34 | buffer = "" 35 | result = @rio.read(nil, buffer) 36 | result.should.equal "hello world" 37 | result.object_id.should.equal buffer.object_id 38 | end 39 | 40 | specify "should rewind to the beginning when #rewind is called" do 41 | @rio.read(1) 42 | @rio.rewind 43 | @rio.read.should.equal "hello world" 44 | end 45 | 46 | specify "should be able to handle gets" do 47 | @rio.gets.should == "hello world" 48 | end 49 | 50 | specify "should be able to handle each" do 51 | array = [] 52 | @rio.each do |data| 53 | array << data 54 | end 55 | array.should.equal(["hello world"]) 56 | end 57 | 58 | specify "should not buffer into a Tempfile if no data has been read yet" do 59 | @rio.instance_variable_get(:@rewindable_io).should.be.nil 60 | end 61 | 62 | specify "should buffer into a Tempfile when data has been consumed for the first time" do 63 | @rio.read(1) 64 | tempfile = @rio.instance_variable_get(:@rewindable_io) 65 | tempfile.should.not.be.nil 66 | @rio.read(1) 67 | tempfile2 = @rio.instance_variable_get(:@rewindable_io) 68 | tempfile2.should.equal tempfile 69 | end 70 | 71 | specify "should close the underlying tempfile upon calling #close" do 72 | @rio.read(1) 73 | tempfile = @rio.instance_variable_get(:@rewindable_io) 74 | @rio.close 75 | tempfile.should.be.closed 76 | end 77 | 78 | specify "should be possibel to call #close when no data has been buffered yet" do 79 | @rio.close 80 | end 81 | 82 | specify "should be possible to call #close multiple times" do 83 | @rio.close 84 | @rio.close 85 | end 86 | end 87 | 88 | context "Rack::RewindableInput" do 89 | context "given an IO object that is already rewindable" do 90 | setup do 91 | @io = StringIO.new("hello world") 92 | end 93 | 94 | it_should_behave_like "a rewindable IO object" 95 | end 96 | 97 | context "given an IO object that is not rewindable" do 98 | setup do 99 | @io = StringIO.new("hello world") 100 | @io.instance_eval do 101 | undef :rewind 102 | end 103 | end 104 | 105 | it_should_behave_like "a rewindable IO object" 106 | end 107 | 108 | context "given an IO object whose rewind method raises Errno::ESPIPE" do 109 | setup do 110 | @io = StringIO.new("hello world") 111 | def @io.rewind 112 | raise Errno::ESPIPE, "You can't rewind this!" 113 | end 114 | end 115 | 116 | it_should_behave_like "a rewindable IO object" 117 | end 118 | end 119 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/session/pool.rb: -------------------------------------------------------------------------------- 1 | # AUTHOR: blink ; blink#ruby-lang@irc.freenode.net 2 | # THANKS: 3 | # apeiros, for session id generation, expiry setup, and threadiness 4 | # sergio, threadiness and bugreps 5 | 6 | require 'rack/session/abstract/id' 7 | require 'thread' 8 | 9 | module Rack 10 | module Session 11 | # Rack::Session::Pool provides simple cookie based session management. 12 | # Session data is stored in a hash held by @pool. 13 | # In the context of a multithreaded environment, sessions being 14 | # committed to the pool is done in a merging manner. 15 | # 16 | # The :drop option is available in rack.session.options if you wish to 17 | # explicitly remove the session from the session cache. 18 | # 19 | # Example: 20 | # myapp = MyRackApp.new 21 | # sessioned = Rack::Session::Pool.new(myapp, 22 | # :domain => 'foo.com', 23 | # :expire_after => 2592000 24 | # ) 25 | # Rack::Handler::WEBrick.run sessioned 26 | 27 | class Pool < Abstract::ID 28 | attr_reader :mutex, :pool 29 | DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge :drop => false 30 | 31 | def initialize(app, options={}) 32 | super 33 | @pool = Hash.new 34 | @mutex = Mutex.new 35 | end 36 | 37 | def generate_sid 38 | loop do 39 | sid = super 40 | break sid unless @pool.key? sid 41 | end 42 | end 43 | 44 | def get_session(env, sid) 45 | session = @pool[sid] if sid 46 | @mutex.lock if env['rack.multithread'] 47 | unless sid and session 48 | env['rack.errors'].puts("Session '#{sid.inspect}' not found, initializing...") if $VERBOSE and not sid.nil? 49 | session = {} 50 | sid = generate_sid 51 | @pool.store sid, session 52 | end 53 | session.instance_variable_set('@old', {}.merge(session)) 54 | return [sid, session] 55 | ensure 56 | @mutex.unlock if env['rack.multithread'] 57 | end 58 | 59 | def set_session(env, session_id, new_session, options) 60 | @mutex.lock if env['rack.multithread'] 61 | session = @pool[session_id] 62 | if options[:renew] or options[:drop] 63 | @pool.delete session_id 64 | return false if options[:drop] 65 | session_id = generate_sid 66 | @pool.store session_id, 0 67 | end 68 | old_session = new_session.instance_variable_get('@old') || {} 69 | session = merge_sessions session_id, old_session, new_session, session 70 | @pool.store session_id, session 71 | return session_id 72 | rescue 73 | warn "#{new_session.inspect} has been lost." 74 | warn $!.inspect 75 | ensure 76 | @mutex.unlock if env['rack.multithread'] 77 | end 78 | 79 | private 80 | 81 | def merge_sessions sid, old, new, cur=nil 82 | cur ||= {} 83 | unless Hash === old and Hash === new 84 | warn 'Bad old or new sessions provided.' 85 | return cur 86 | end 87 | 88 | delete = old.keys - new.keys 89 | warn "//@#{sid}: dropping #{delete*','}" if $DEBUG and not delete.empty? 90 | delete.each{|k| cur.delete k } 91 | 92 | update = new.keys.select{|k| new[k] != old[k] } 93 | warn "//@#{sid}: updating #{update*','}" if $DEBUG and not update.empty? 94 | update.each{|k| cur[k] = new[k] } 95 | 96 | cur 97 | end 98 | end 99 | end 100 | end 101 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/showstatus.rb: -------------------------------------------------------------------------------- 1 | require 'erb' 2 | require 'rack/request' 3 | require 'rack/utils' 4 | 5 | module Rack 6 | # Rack::ShowStatus catches all empty responses the app it wraps and 7 | # replaces them with a site explaining the error. 8 | # 9 | # Additional details can be put into rack.showstatus.detail 10 | # and will be shown as HTML. If such details exist, the error page 11 | # is always rendered, even if the reply was not empty. 12 | 13 | class ShowStatus 14 | def initialize(app) 15 | @app = app 16 | @template = ERB.new(TEMPLATE) 17 | end 18 | 19 | def call(env) 20 | status, headers, body = @app.call(env) 21 | headers = Utils::HeaderHash.new(headers) 22 | empty = headers['Content-Length'].to_i <= 0 23 | 24 | # client or server error, or explicit message 25 | if (status.to_i >= 400 && empty) || env["rack.showstatus.detail"] 26 | req = Rack::Request.new(env) 27 | message = Rack::Utils::HTTP_STATUS_CODES[status.to_i] || status.to_s 28 | detail = env["rack.showstatus.detail"] || message 29 | body = @template.result(binding) 30 | size = Rack::Utils.bytesize(body) 31 | [status, headers.merge("Content-Type" => "text/html", "Content-Length" => size.to_s), [body]] 32 | else 33 | [status, headers, body] 34 | end 35 | end 36 | 37 | def h(obj) # :nodoc: 38 | case obj 39 | when String 40 | Utils.escape_html(obj) 41 | else 42 | Utils.escape_html(obj.inspect) 43 | end 44 | end 45 | 46 | # :stopdoc: 47 | 48 | # adapted from Django 49 | # Copyright (c) 2005, the Lawrence Journal-World 50 | # Used under the modified BSD license: 51 | # http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5 52 | TEMPLATE = <<'HTML' 53 | 54 | 55 | 56 | 57 | <%=h message %> at <%=h req.script_name + req.path_info %> 58 | 59 | 76 | 77 | 78 |
79 |

<%=h message %> (<%= status.to_i %>)

80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 |
Request Method:<%=h req.request_method %>
Request URL:<%=h req.url %>
90 |
91 |
92 |

<%= detail %>

93 |
94 | 95 |
96 |

97 | You're seeing this error because you use Rack::ShowStatus. 98 |

99 |
100 | 101 | 102 | HTML 103 | 104 | # :startdoc: 105 | end 106 | end 107 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake/clean' 2 | require 'rake/testtask' 3 | require 'fileutils' 4 | 5 | task :default => :test 6 | task :spec => :test 7 | 8 | def source_version 9 | line = File.read('lib/sinatra/base.rb')[/^\s*VERSION = .*/] 10 | line.match(/.*VERSION = '(.*)'/)[1] 11 | end 12 | 13 | # SPECS =============================================================== 14 | 15 | Rake::TestTask.new(:test) do |t| 16 | t.test_files = FileList['test/*_test.rb'] 17 | t.ruby_opts = ['-rubygems -I.'] if defined? Gem 18 | end 19 | 20 | # Rcov ================================================================ 21 | namespace :test do 22 | desc 'Mesures test coverage' 23 | task :coverage do 24 | rm_f "coverage" 25 | rcov = "rcov --text-summary --test-unit-only -Ilib" 26 | system("#{rcov} --no-html --no-color test/*_test.rb") 27 | end 28 | end 29 | 30 | # Website ============================================================= 31 | # Building docs requires HAML and the hanna gem: 32 | # gem install mislav-hanna --source=http://gems.github.com 33 | 34 | desc 'Generate RDoc under doc/api' 35 | task 'doc' => ['doc:api'] 36 | 37 | task 'doc:api' => ['doc/api/index.html'] 38 | 39 | file 'doc/api/index.html' => FileList['lib/**/*.rb','README.rdoc'] do |f| 40 | require 'rbconfig' 41 | hanna = RbConfig::CONFIG['ruby_install_name'].sub('ruby', 'hanna') 42 | rb_files = f.prerequisites 43 | sh((<<-end).gsub(/\s+/, ' ')) 44 | #{hanna} 45 | --charset utf8 46 | --fmt html 47 | --inline-source 48 | --line-numbers 49 | --main README.rdoc 50 | --op doc/api 51 | --title 'Sinatra API Documentation' 52 | #{rb_files.join(' ')} 53 | end 54 | end 55 | CLEAN.include 'doc/api' 56 | 57 | # PACKAGING ============================================================ 58 | 59 | if defined?(Gem) 60 | # Load the gemspec using the same limitations as github 61 | def spec 62 | require 'rubygems' unless defined? Gem::Specification 63 | @spec ||= eval(File.read('sinatra.gemspec')) 64 | end 65 | 66 | def package(ext='') 67 | "pkg/sinatra-#{spec.version}" + ext 68 | end 69 | 70 | desc 'Build packages' 71 | task :package => %w[.gem .tar.gz].map {|e| package(e)} 72 | 73 | desc 'Build and install as local gem' 74 | task :install => package('.gem') do 75 | sh "gem install #{package('.gem')}" 76 | end 77 | 78 | directory 'pkg/' 79 | CLOBBER.include('pkg') 80 | 81 | file package('.gem') => %w[pkg/ sinatra.gemspec] + spec.files do |f| 82 | sh "gem build sinatra.gemspec" 83 | mv File.basename(f.name), f.name 84 | end 85 | 86 | file package('.tar.gz') => %w[pkg/] + spec.files do |f| 87 | sh <<-SH 88 | git archive \ 89 | --prefix=sinatra-#{source_version}/ \ 90 | --format=tar \ 91 | HEAD | gzip > #{f.name} 92 | SH 93 | end 94 | 95 | task 'sinatra.gemspec' => FileList['{lib,test,compat}/**','Rakefile','CHANGES','*.rdoc'] do |f| 96 | # read spec file and split out manifest section 97 | spec = File.read(f.name) 98 | head, manifest, tail = spec.split(" # = MANIFEST =\n") 99 | # replace version and date 100 | head.sub!(/\.version = '.*'/, ".version = '#{source_version}'") 101 | head.sub!(/\.date = '.*'/, ".date = '#{Date.today.to_s}'") 102 | # determine file list from git ls-files 103 | files = `git ls-files`. 104 | split("\n"). 105 | sort. 106 | reject{ |file| file =~ /^\./ }. 107 | reject { |file| file =~ /^doc/ }. 108 | map{ |file| " #{file}" }. 109 | join("\n") 110 | # piece file back together and write... 111 | manifest = " s.files = %w[\n#{files}\n ]\n" 112 | spec = [head,manifest,tail].join(" # = MANIFEST =\n") 113 | File.open(f.name, 'w') { |io| io.write(spec) } 114 | puts "updated #{f.name}" 115 | end 116 | end 117 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/response.rb: -------------------------------------------------------------------------------- 1 | require 'rack/request' 2 | require 'rack/utils' 3 | 4 | module Rack 5 | # Rack::Response provides a convenient interface to create a Rack 6 | # response. 7 | # 8 | # It allows setting of headers and cookies, and provides useful 9 | # defaults (a OK response containing HTML). 10 | # 11 | # You can use Response#write to iteratively generate your response, 12 | # but note that this is buffered by Rack::Response until you call 13 | # +finish+. +finish+ however can take a block inside which calls to 14 | # +write+ are syncronous with the Rack response. 15 | # 16 | # Your application's +call+ should end returning Response#finish. 17 | 18 | class Response 19 | attr_accessor :length 20 | 21 | def initialize(body=[], status=200, header={}, &block) 22 | @status = status.to_i 23 | @header = Utils::HeaderHash.new({"Content-Type" => "text/html"}. 24 | merge(header)) 25 | 26 | @writer = lambda { |x| @body << x } 27 | @block = nil 28 | @length = 0 29 | 30 | @body = [] 31 | 32 | if body.respond_to? :to_str 33 | write body.to_str 34 | elsif body.respond_to?(:each) 35 | body.each { |part| 36 | write part.to_s 37 | } 38 | else 39 | raise TypeError, "stringable or iterable required" 40 | end 41 | 42 | yield self if block_given? 43 | end 44 | 45 | attr_reader :header 46 | attr_accessor :status, :body 47 | 48 | def [](key) 49 | header[key] 50 | end 51 | 52 | def []=(key, value) 53 | header[key] = value 54 | end 55 | 56 | def set_cookie(key, value) 57 | Utils.set_cookie_header!(header, key, value) 58 | end 59 | 60 | def delete_cookie(key, value={}) 61 | Utils.delete_cookie_header!(header, key, value) 62 | end 63 | 64 | def redirect(target, status=302) 65 | self.status = status 66 | self["Location"] = target 67 | end 68 | 69 | def finish(&block) 70 | @block = block 71 | 72 | if [204, 304].include?(status.to_i) 73 | header.delete "Content-Type" 74 | [status.to_i, header, []] 75 | else 76 | [status.to_i, header, self] 77 | end 78 | end 79 | alias to_a finish # For *response 80 | 81 | def each(&callback) 82 | @body.each(&callback) 83 | @writer = callback 84 | @block.call(self) if @block 85 | end 86 | 87 | # Append to body and update Content-Length. 88 | # 89 | # NOTE: Do not mix #write and direct #body access! 90 | # 91 | def write(str) 92 | s = str.to_s 93 | @length += Rack::Utils.bytesize(s) 94 | @writer.call s 95 | 96 | header["Content-Length"] = @length.to_s 97 | str 98 | end 99 | 100 | def close 101 | body.close if body.respond_to?(:close) 102 | end 103 | 104 | def empty? 105 | @block == nil && @body.empty? 106 | end 107 | 108 | alias headers header 109 | 110 | module Helpers 111 | def invalid?; @status < 100 || @status >= 600; end 112 | 113 | def informational?; @status >= 100 && @status < 200; end 114 | def successful?; @status >= 200 && @status < 300; end 115 | def redirection?; @status >= 300 && @status < 400; end 116 | def client_error?; @status >= 400 && @status < 500; end 117 | def server_error?; @status >= 500 && @status < 600; end 118 | 119 | def ok?; @status == 200; end 120 | def forbidden?; @status == 403; end 121 | def not_found?; @status == 404; end 122 | 123 | def redirect?; [301, 302, 303, 307].include? @status; end 124 | def empty?; [201, 204, 304].include? @status; end 125 | 126 | # Headers 127 | attr_reader :headers, :original_headers 128 | 129 | def include?(header) 130 | !!headers[header] 131 | end 132 | 133 | def content_type 134 | headers["Content-Type"] 135 | end 136 | 137 | def content_length 138 | cl = headers["Content-Length"] 139 | cl ? cl.to_i : cl 140 | end 141 | 142 | def location 143 | headers["Location"] 144 | end 145 | end 146 | 147 | include Helpers 148 | end 149 | end 150 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rackup.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | require 'testrequest' 3 | require 'rack/server' 4 | require 'open3' 5 | 6 | begin 7 | require "mongrel" 8 | 9 | context "rackup" do 10 | include TestRequest::Helpers 11 | 12 | def run_rackup(*args) 13 | options = args.last.is_a?(Hash) ? args.pop : {} 14 | flags = args.first 15 | @host = options[:host] || "0.0.0.0" 16 | @port = options[:port] || 9292 17 | 18 | Dir.chdir("#{root}/test/rackup") do 19 | @in, @rackup, @err = Open3.popen3("#{Gem.ruby} -S #{rackup} #{flags}") 20 | end 21 | 22 | return if options[:port] == false 23 | 24 | # Wait until the server is available 25 | begin 26 | GET("/") 27 | rescue 28 | sleep 0.05 29 | retry 30 | end 31 | end 32 | 33 | def output 34 | @rackup.read 35 | end 36 | 37 | after do 38 | # This doesn't actually return a response, so we rescue 39 | GET "/die" rescue nil 40 | 41 | Dir["#{root}/**/*.pid"].each do |file| 42 | File.delete(file) 43 | end 44 | 45 | File.delete("#{root}/log_output") if File.exist?("#{root}/log_output") 46 | end 47 | 48 | specify "rackup" do 49 | run_rackup 50 | response["PATH_INFO"].should.equal '/' 51 | response["test.$DEBUG"].should.be false 52 | response["test.$EVAL"].should.be nil 53 | response["test.$VERBOSE"].should.be false 54 | response["test.Ping"].should.be nil 55 | response["SERVER_SOFTWARE"].should.not =~ /webrick/ 56 | end 57 | 58 | specify "rackup --help" do 59 | run_rackup "--help", :port => false 60 | output.should.match /--port/ 61 | end 62 | 63 | specify "rackup --port" do 64 | run_rackup "--port 9000", :port => 9000 65 | response["SERVER_PORT"].should.equal "9000" 66 | end 67 | 68 | specify "rackup --debug" do 69 | run_rackup "--debug" 70 | response["test.$DEBUG"].should.be true 71 | end 72 | 73 | specify "rackup --eval" do 74 | run_rackup %{--eval "BUKKIT = 'BUKKIT'"} 75 | response["test.$EVAL"].should.equal "BUKKIT" 76 | end 77 | 78 | specify "rackup --warn" do 79 | run_rackup %{--warn} 80 | response["test.$VERBOSE"].should.be true 81 | end 82 | 83 | specify "rackup --include" do 84 | run_rackup %{--include /foo/bar} 85 | response["test.$LOAD_PATH"].should.include "/foo/bar" 86 | end 87 | 88 | specify "rackup --require" do 89 | run_rackup %{--require ping} 90 | response["test.Ping"].should.equal "constant" 91 | end 92 | 93 | specify "rackup --server" do 94 | run_rackup %{--server webrick} 95 | response["SERVER_SOFTWARE"].should =~ /webrick/i 96 | end 97 | 98 | specify "rackup --host" do 99 | run_rackup %{--host 127.0.0.1}, :host => "127.0.0.1" 100 | response["REMOTE_ADDR"].should.equal "127.0.0.1" 101 | end 102 | 103 | specify "rackup --daemonize --pid" do 104 | run_rackup %{--daemonize --pid testing.pid} 105 | status.should.be 200 106 | @rackup.should.be.eof? 107 | Dir["#{root}/**/testing.pid"].should.not.be.empty? 108 | end 109 | 110 | specify "rackup --pid" do 111 | run_rackup %{--pid testing.pid} 112 | status.should.be 200 113 | Dir["#{root}/**/testing.pid"].should.not.be.empty? 114 | end 115 | 116 | specify "rackup --version" do 117 | run_rackup %{--version}, :port => false 118 | output.should =~ /1.0/ 119 | end 120 | 121 | specify "rackup --env development includes lint" do 122 | run_rackup 123 | GET("/broken_lint") 124 | status.should.be 500 125 | end 126 | 127 | specify "rackup --env deployment does not include lint" do 128 | run_rackup %{--env deployment} 129 | GET("/broken_lint") 130 | status.should.be 200 131 | end 132 | 133 | specify "rackup --env none does not include lint" do 134 | run_rackup %{--env none} 135 | GET("/broken_lint") 136 | status.should.be 200 137 | end 138 | 139 | specify "rackup --env deployment does log" do 140 | run_rackup %{--env deployment} 141 | log = File.read(response["test.stderr"]) 142 | log.should.be.empty? 143 | end 144 | 145 | specify "rackup --env none does not log" do 146 | run_rackup %{--env none} 147 | GET("/") 148 | log = File.read(response["test.stderr"]) 149 | log.should.be.empty? 150 | end 151 | end 152 | rescue LoadError 153 | $stderr.puts "Skipping rackup --server tests (mongrel is required). `gem install thin` and try again." 154 | end -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/lib/rack/directory.rb: -------------------------------------------------------------------------------- 1 | require 'time' 2 | require 'rack/utils' 3 | require 'rack/mime' 4 | 5 | module Rack 6 | # Rack::Directory serves entries below the +root+ given, according to the 7 | # path info of the Rack request. If a directory is found, the file's contents 8 | # will be presented in an html based index. If a file is found, the env will 9 | # be passed to the specified +app+. 10 | # 11 | # If +app+ is not specified, a Rack::File of the same +root+ will be used. 12 | 13 | class Directory 14 | DIR_FILE = "%s%s%s%s" 15 | DIR_PAGE = <<-PAGE 16 | 17 | %s 18 | 19 | 26 | 27 |

%s

28 |
29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | %s 37 |
NameSizeTypeLast Modified
38 |
39 | 40 | PAGE 41 | 42 | attr_reader :files 43 | attr_accessor :root, :path 44 | 45 | def initialize(root, app=nil) 46 | @root = F.expand_path(root) 47 | @app = app || Rack::File.new(@root) 48 | end 49 | 50 | def call(env) 51 | dup._call(env) 52 | end 53 | 54 | F = ::File 55 | 56 | def _call(env) 57 | @env = env 58 | @script_name = env['SCRIPT_NAME'] 59 | @path_info = Utils.unescape(env['PATH_INFO']) 60 | 61 | if forbidden = check_forbidden 62 | forbidden 63 | else 64 | @path = F.join(@root, @path_info) 65 | list_path 66 | end 67 | end 68 | 69 | def check_forbidden 70 | return unless @path_info.include? ".." 71 | 72 | body = "Forbidden\n" 73 | size = Rack::Utils.bytesize(body) 74 | return [403, {"Content-Type" => "text/plain", 75 | "Content-Length" => size.to_s, 76 | "X-Cascade" => "pass"}, [body]] 77 | end 78 | 79 | def list_directory 80 | @files = [['../','Parent Directory','','','']] 81 | glob = F.join(@path, '*') 82 | 83 | Dir[glob].sort.each do |node| 84 | stat = stat(node) 85 | next unless stat 86 | basename = F.basename(node) 87 | ext = F.extname(node) 88 | 89 | url = F.join(@script_name, @path_info, basename) 90 | size = stat.size 91 | type = stat.directory? ? 'directory' : Mime.mime_type(ext) 92 | size = stat.directory? ? '-' : filesize_format(size) 93 | mtime = stat.mtime.httpdate 94 | url << '/' if stat.directory? 95 | basename << '/' if stat.directory? 96 | 97 | @files << [ url, basename, size, type, mtime ] 98 | end 99 | 100 | return [ 200, {'Content-Type'=>'text/html; charset=utf-8'}, self ] 101 | end 102 | 103 | def stat(node, max = 10) 104 | F.stat(node) 105 | rescue Errno::ENOENT, Errno::ELOOP 106 | return nil 107 | end 108 | 109 | # TODO: add correct response if not readable, not sure if 404 is the best 110 | # option 111 | def list_path 112 | @stat = F.stat(@path) 113 | 114 | if @stat.readable? 115 | return @app.call(@env) if @stat.file? 116 | return list_directory if @stat.directory? 117 | else 118 | raise Errno::ENOENT, 'No such file or directory' 119 | end 120 | 121 | rescue Errno::ENOENT, Errno::ELOOP 122 | return entity_not_found 123 | end 124 | 125 | def entity_not_found 126 | body = "Entity not found: #{@path_info}\n" 127 | size = Rack::Utils.bytesize(body) 128 | return [404, {"Content-Type" => "text/plain", 129 | "Content-Length" => size.to_s, 130 | "X-Cascade" => "pass"}, [body]] 131 | end 132 | 133 | def each 134 | show_path = @path.sub(/^#{@root}/,'') 135 | files = @files.map{|f| DIR_FILE % f }*"\n" 136 | page = DIR_PAGE % [ show_path, show_path , files ] 137 | page.each_line{|l| yield l } 138 | end 139 | 140 | # Stolen from Ramaze 141 | 142 | FILESIZE_FORMAT = [ 143 | ['%.1fT', 1 << 40], 144 | ['%.1fG', 1 << 30], 145 | ['%.1fM', 1 << 20], 146 | ['%.1fK', 1 << 10], 147 | ] 148 | 149 | def filesize_format(int) 150 | FILESIZE_FORMAT.each do |format, size| 151 | return format % (int.to_f / size) if int >= size 152 | end 153 | 154 | int.to_s + 'B' 155 | end 156 | end 157 | end 158 | -------------------------------------------------------------------------------- /vendor/gems/rack-1.1.0/test/spec_rack_webrick.rb: -------------------------------------------------------------------------------- 1 | require 'test/spec' 2 | 3 | require 'rack/handler/webrick' 4 | require 'rack/lint' 5 | require 'rack/response' 6 | require 'testrequest' 7 | 8 | Thread.abort_on_exception = true 9 | 10 | context "Rack::Handler::WEBrick" do 11 | include TestRequest::Helpers 12 | 13 | setup do 14 | @server = WEBrick::HTTPServer.new(:Host => @host='0.0.0.0', 15 | :Port => @port=9202, 16 | :Logger => WEBrick::Log.new(nil, WEBrick::BasicLog::WARN), 17 | :AccessLog => []) 18 | @server.mount "/test", Rack::Handler::WEBrick, 19 | Rack::Lint.new(TestRequest.new) 20 | Thread.new { @server.start } 21 | trap(:INT) { @server.shutdown } 22 | end 23 | 24 | specify "should respond" do 25 | lambda { 26 | GET("/test") 27 | }.should.not.raise 28 | end 29 | 30 | specify "should be a WEBrick" do 31 | GET("/test") 32 | status.should.be 200 33 | response["SERVER_SOFTWARE"].should =~ /WEBrick/ 34 | response["HTTP_VERSION"].should.equal "HTTP/1.1" 35 | response["SERVER_PROTOCOL"].should.equal "HTTP/1.1" 36 | response["SERVER_PORT"].should.equal "9202" 37 | response["SERVER_NAME"].should.equal "0.0.0.0" 38 | end 39 | 40 | specify "should have rack headers" do 41 | GET("/test") 42 | response["rack.version"].should.equal [1,1] 43 | response["rack.multithread"].should.be true 44 | response["rack.multiprocess"].should.be false 45 | response["rack.run_once"].should.be false 46 | end 47 | 48 | specify "should have CGI headers on GET" do 49 | GET("/test") 50 | response["REQUEST_METHOD"].should.equal "GET" 51 | response["SCRIPT_NAME"].should.equal "/test" 52 | response["REQUEST_PATH"].should.equal "/" 53 | response["PATH_INFO"].should.be.equal "" 54 | response["QUERY_STRING"].should.equal "" 55 | response["test.postdata"].should.equal "" 56 | 57 | GET("/test/foo?quux=1") 58 | response["REQUEST_METHOD"].should.equal "GET" 59 | response["SCRIPT_NAME"].should.equal "/test" 60 | response["REQUEST_PATH"].should.equal "/" 61 | response["PATH_INFO"].should.equal "/foo" 62 | response["QUERY_STRING"].should.equal "quux=1" 63 | 64 | GET("/test/foo%25encoding?quux=1") 65 | response["REQUEST_METHOD"].should.equal "GET" 66 | response["SCRIPT_NAME"].should.equal "/test" 67 | response["REQUEST_PATH"].should.equal "/" 68 | response["PATH_INFO"].should.equal "/foo%25encoding" 69 | response["QUERY_STRING"].should.equal "quux=1" 70 | end 71 | 72 | specify "should have CGI headers on POST" do 73 | POST("/test", {"rack-form-data" => "23"}, {'X-test-header' => '42'}) 74 | status.should.equal 200 75 | response["REQUEST_METHOD"].should.equal "POST" 76 | response["SCRIPT_NAME"].should.equal "/test" 77 | response["REQUEST_PATH"].should.equal "/" 78 | response["QUERY_STRING"].should.equal "" 79 | response["HTTP_X_TEST_HEADER"].should.equal "42" 80 | response["test.postdata"].should.equal "rack-form-data=23" 81 | end 82 | 83 | specify "should support HTTP auth" do 84 | GET("/test", {:user => "ruth", :passwd => "secret"}) 85 | response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ=" 86 | end 87 | 88 | specify "should set status" do 89 | GET("/test?secret") 90 | status.should.equal 403 91 | response["rack.url_scheme"].should.equal "http" 92 | end 93 | 94 | specify "should correctly set cookies" do 95 | @server.mount "/cookie-test", Rack::Handler::WEBrick, 96 | Rack::Lint.new(lambda { |req| 97 | res = Rack::Response.new 98 | res.set_cookie "one", "1" 99 | res.set_cookie "two", "2" 100 | res.finish 101 | }) 102 | 103 | Net::HTTP.start(@host, @port) { |http| 104 | res = http.get("/cookie-test") 105 | res.code.to_i.should.equal 200 106 | res.get_fields("set-cookie").should.equal ["one=1", "two=2"] 107 | } 108 | end 109 | 110 | specify "should provide a .run" do 111 | block_ran = false 112 | catch(:done) { 113 | Rack::Handler::WEBrick.run(lambda {}, 114 | {:Port => 9210, 115 | :Logger => WEBrick::Log.new(nil, WEBrick::BasicLog::WARN), 116 | :AccessLog => []}) { |server| 117 | block_ran = true 118 | server.should.be.kind_of WEBrick::HTTPServer 119 | @s = server 120 | throw :done 121 | } 122 | } 123 | block_ran.should.be true 124 | @s.shutdown 125 | end 126 | 127 | teardown do 128 | @server.shutdown 129 | end 130 | end 131 | -------------------------------------------------------------------------------- /vendor/gems/sinatra-1.0/test/templates_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/helper' 2 | 3 | class TestTemplate < Tilt::Template 4 | def prepare 5 | end 6 | alias compile! prepare # for tilt < 0.7 7 | 8 | def evaluate(scope, locals={}, &block) 9 | inner = block ? block.call : '' 10 | data + inner 11 | end 12 | 13 | Tilt.register 'test', self 14 | end 15 | 16 | class TemplatesTest < Test::Unit::TestCase 17 | def render_app(base=Sinatra::Base, &block) 18 | mock_app(base) { 19 | set :views, File.dirname(__FILE__) + '/views' 20 | get '/', &block 21 | template(:layout3) { "Layout 3!\n" } 22 | } 23 | get '/' 24 | end 25 | 26 | def with_default_layout 27 | layout = File.dirname(__FILE__) + '/views/layout.test' 28 | File.open(layout, 'wb') { |io| io.write "Layout!\n" } 29 | yield 30 | ensure 31 | File.unlink(layout) rescue nil 32 | end 33 | 34 | it 'renders String templates directly' do 35 | render_app { render :test, 'Hello World' } 36 | assert ok? 37 | assert_equal 'Hello World', body 38 | end 39 | 40 | it 'renders Proc templates using the call result' do 41 | render_app { render :test, Proc.new {'Hello World'} } 42 | assert ok? 43 | assert_equal 'Hello World', body 44 | end 45 | 46 | it 'looks up Symbol templates in views directory' do 47 | render_app { render :test, :hello } 48 | assert ok? 49 | assert_equal "Hello World!\n", body 50 | end 51 | 52 | it 'uses the default layout template if not explicitly overridden' do 53 | with_default_layout do 54 | render_app { render :test, :hello } 55 | assert ok? 56 | assert_equal "Layout!\nHello World!\n", body 57 | end 58 | end 59 | 60 | it 'uses the default layout template if not really overriden' do 61 | with_default_layout do 62 | render_app { render :test, :hello, :layout => true } 63 | assert ok? 64 | assert_equal "Layout!\nHello World!\n", body 65 | end 66 | end 67 | 68 | it 'uses the layout template specified' do 69 | render_app { render :test, :hello, :layout => :layout2 } 70 | assert ok? 71 | assert_equal "Layout 2!\nHello World!\n", body 72 | end 73 | 74 | it 'uses layout templates defined with the #template method' do 75 | render_app { render :test, :hello, :layout => :layout3 } 76 | assert ok? 77 | assert_equal "Layout 3!\nHello World!\n", body 78 | end 79 | 80 | it 'loads templates from source file' do 81 | mock_app { enable :inline_templates } 82 | assert_equal "this is foo\n\n", @app.templates[:foo][0] 83 | assert_equal "X\n= yield\nX\n", @app.templates[:layout][0] 84 | end 85 | 86 | it 'loads templates from given source file' do 87 | mock_app { set :inline_templates, __FILE__ } 88 | assert_equal "this is foo\n\n", @app.templates[:foo][0] 89 | end 90 | 91 | test 'inline_templates ignores IO errors' do 92 | assert_nothing_raised { 93 | mock_app { 94 | set :inline_templates, '/foo/bar' 95 | } 96 | } 97 | 98 | assert @app.templates.empty? 99 | end 100 | 101 | it 'loads templates from specified views directory' do 102 | render_app { render :test, :hello, :views => options.views + '/foo' } 103 | 104 | assert_equal "from another views directory\n", body 105 | end 106 | 107 | it 'passes locals to the layout' do 108 | mock_app { 109 | template :my_layout do 110 | 'Hello <%= name %>!<%= yield %>' 111 | end 112 | 113 | get '/' do 114 | erb '

content

', { :layout => :my_layout }, { :name => 'Mike'} 115 | end 116 | } 117 | 118 | get '/' 119 | assert ok? 120 | assert_equal 'Hello Mike!

content

', body 121 | end 122 | 123 | it 'loads templates defined in subclasses' do 124 | base = Class.new(Sinatra::Base) 125 | base.template(:foo) { 'bar' } 126 | render_app(base) { render :test, :foo } 127 | assert ok? 128 | assert_equal 'bar', body 129 | end 130 | 131 | it 'uses templates in superclasses before subclasses' do 132 | base = Class.new(Sinatra::Base) 133 | base.template(:foo) { 'template in superclass' } 134 | assert_equal 'template in superclass', base.templates[:foo].first.call 135 | 136 | mock_app(base) { 137 | set :views, File.dirname(__FILE__) + '/views' 138 | template(:foo) { 'template in subclass' } 139 | get('/') { render :test, :foo } 140 | } 141 | assert_equal 'template in subclass', @app.templates[:foo].first.call 142 | 143 | get '/' 144 | assert ok? 145 | assert_equal 'template in subclass', body 146 | end 147 | end 148 | 149 | # __END__ : this is not the real end of the script. 150 | 151 | __END__ 152 | 153 | @@ foo 154 | this is foo 155 | 156 | @@ layout 157 | X 158 | = yield 159 | X 160 | --------------------------------------------------------------------------------