lack 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/rackup +5 -0
- data/lib/rack.rb +26 -0
- data/lib/rack/body_proxy.rb +39 -0
- data/lib/rack/builder.rb +166 -0
- data/lib/rack/handler.rb +63 -0
- data/lib/rack/handler/webrick.rb +120 -0
- data/lib/rack/mime.rb +661 -0
- data/lib/rack/mock.rb +198 -0
- data/lib/rack/multipart.rb +31 -0
- data/lib/rack/multipart/generator.rb +93 -0
- data/lib/rack/multipart/parser.rb +239 -0
- data/lib/rack/multipart/uploaded_file.rb +34 -0
- data/lib/rack/request.rb +394 -0
- data/lib/rack/response.rb +160 -0
- data/lib/rack/server.rb +258 -0
- data/lib/rack/server/options.rb +121 -0
- data/lib/rack/utils.rb +653 -0
- data/lib/rack/version.rb +3 -0
- data/spec/spec_helper.rb +1 -0
- data/test/builder/anything.rb +5 -0
- data/test/builder/comment.ru +4 -0
- data/test/builder/end.ru +5 -0
- data/test/builder/line.ru +1 -0
- data/test/builder/options.ru +2 -0
- data/test/multipart/bad_robots +259 -0
- data/test/multipart/binary +0 -0
- data/test/multipart/content_type_and_no_filename +6 -0
- data/test/multipart/empty +10 -0
- data/test/multipart/fail_16384_nofile +814 -0
- data/test/multipart/file1.txt +1 -0
- data/test/multipart/filename_and_modification_param +7 -0
- data/test/multipart/filename_and_no_name +6 -0
- data/test/multipart/filename_with_escaped_quotes +6 -0
- data/test/multipart/filename_with_escaped_quotes_and_modification_param +7 -0
- data/test/multipart/filename_with_percent_escaped_quotes +6 -0
- data/test/multipart/filename_with_unescaped_percentages +6 -0
- data/test/multipart/filename_with_unescaped_percentages2 +6 -0
- data/test/multipart/filename_with_unescaped_percentages3 +6 -0
- data/test/multipart/filename_with_unescaped_quotes +6 -0
- data/test/multipart/ie +6 -0
- data/test/multipart/invalid_character +6 -0
- data/test/multipart/mixed_files +21 -0
- data/test/multipart/nested +10 -0
- data/test/multipart/none +9 -0
- data/test/multipart/semicolon +6 -0
- data/test/multipart/text +15 -0
- data/test/multipart/webkit +32 -0
- data/test/rackup/config.ru +31 -0
- data/test/registering_handler/rack/handler/registering_myself.rb +8 -0
- data/test/spec_body_proxy.rb +69 -0
- data/test/spec_builder.rb +223 -0
- data/test/spec_chunked.rb +101 -0
- data/test/spec_file.rb +221 -0
- data/test/spec_handler.rb +59 -0
- data/test/spec_head.rb +45 -0
- data/test/spec_lint.rb +522 -0
- data/test/spec_mime.rb +51 -0
- data/test/spec_mock.rb +277 -0
- data/test/spec_multipart.rb +547 -0
- data/test/spec_recursive.rb +72 -0
- data/test/spec_request.rb +1199 -0
- data/test/spec_response.rb +343 -0
- data/test/spec_rewindable_input.rb +118 -0
- data/test/spec_sendfile.rb +130 -0
- data/test/spec_server.rb +167 -0
- data/test/spec_utils.rb +635 -0
- data/test/spec_webrick.rb +184 -0
- data/test/testrequest.rb +78 -0
- data/test/unregistered_handler/rack/handler/unregistered.rb +7 -0
- data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +7 -0
- metadata +240 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: dda0b695e3c3455b23e1542ba0cfada50c652231
         | 
| 4 | 
            +
              data.tar.gz: 45f0569e005d5aadac54f4990cb8fecc59597d0b
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: 5e333d7a3b48e420b0d19cbe26d10110838eecf8cb08d95790d7ea9b290f40ad4d6ab371d6dc1a3a9b8e8a22e3f12dca1b44c07c26a03fc27ff433962f442d69
         | 
| 7 | 
            +
              data.tar.gz: 79ec2313189a582c05458581633f1abe2beb48ab1fae360647da7ea3d18045d13fbbb1717740e701e4e49a607d9036c3630fc0ba785428dc67cb8065dcc36873
         | 
    
        data/bin/rackup
    ADDED
    
    
    
        data/lib/rack.rb
    ADDED
    
    | @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            # Copyright (C) 2007, 2008, 2009, 2010 Christian Neukirchen <purl.org/net/chneukirchen>
         | 
| 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 | 
            +
            require "optparse"
         | 
| 9 | 
            +
            require "fileutils"
         | 
| 10 | 
            +
            require "set"
         | 
| 11 | 
            +
            require "tempfile"
         | 
| 12 | 
            +
            require "rack/multipart"
         | 
| 13 | 
            +
            require "time"
         | 
| 14 | 
            +
            require "uri/common"
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            module Rack
         | 
| 17 | 
            +
              require_relative "rack/version"
         | 
| 18 | 
            +
              require_relative "rack/body_proxy"
         | 
| 19 | 
            +
              require_relative "rack/builder"
         | 
| 20 | 
            +
              require_relative "rack/handler"
         | 
| 21 | 
            +
              require_relative "rack/mime"
         | 
| 22 | 
            +
              require_relative "rack/request"
         | 
| 23 | 
            +
              require_relative "rack/response"
         | 
| 24 | 
            +
              require_relative "rack/server"
         | 
| 25 | 
            +
              require_relative "rack/utils"
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,39 @@ | |
| 1 | 
            +
            module Rack
         | 
| 2 | 
            +
              class BodyProxy
         | 
| 3 | 
            +
                def initialize(body, &block)
         | 
| 4 | 
            +
                  @body, @block, @closed = body, block, false
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def respond_to?(*args)
         | 
| 8 | 
            +
                  return false if args.first.to_s =~ /^to_ary$/
         | 
| 9 | 
            +
                  super or @body.respond_to?(*args)
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def close
         | 
| 13 | 
            +
                  return if @closed
         | 
| 14 | 
            +
                  @closed = true
         | 
| 15 | 
            +
                  begin
         | 
| 16 | 
            +
                    @body.close if @body.respond_to? :close
         | 
| 17 | 
            +
                  ensure
         | 
| 18 | 
            +
                    @block.call
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                def closed?
         | 
| 23 | 
            +
                  @closed
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                # N.B. This method is a special case to address the bug described by #434.
         | 
| 27 | 
            +
                # We are applying this special case for #each only. Future bugs of this
         | 
| 28 | 
            +
                # class will be handled by requesting users to patch their ruby
         | 
| 29 | 
            +
                # implementation, to save adding too many methods in this class.
         | 
| 30 | 
            +
                def each(*args, &block)
         | 
| 31 | 
            +
                  @body.each(*args, &block)
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def method_missing(*args, &block)
         | 
| 35 | 
            +
                  super if args.first.to_s =~ /^to_ary$/
         | 
| 36 | 
            +
                  @body.__send__(*args, &block)
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
            end
         | 
    
        data/lib/rack/builder.rb
    ADDED
    
    | @@ -0,0 +1,166 @@ | |
| 1 | 
            +
            module Rack
         | 
| 2 | 
            +
              # Rack::Builder implements a small DSL to iteratively construct Rack
         | 
| 3 | 
            +
              # applications.
         | 
| 4 | 
            +
              #
         | 
| 5 | 
            +
              # Example:
         | 
| 6 | 
            +
              #
         | 
| 7 | 
            +
              #  require 'rack/lobster'
         | 
| 8 | 
            +
              #  app = Rack::Builder.new do
         | 
| 9 | 
            +
              #    use Rack::CommonLogger
         | 
| 10 | 
            +
              #    use Rack::ShowExceptions
         | 
| 11 | 
            +
              #    map "/lobster" do
         | 
| 12 | 
            +
              #      use Rack::Lint
         | 
| 13 | 
            +
              #      run Rack::Lobster.new
         | 
| 14 | 
            +
              #    end
         | 
| 15 | 
            +
              #  end
         | 
| 16 | 
            +
              #
         | 
| 17 | 
            +
              #  run app
         | 
| 18 | 
            +
              #
         | 
| 19 | 
            +
              # Or
         | 
| 20 | 
            +
              #
         | 
| 21 | 
            +
              #  app = Rack::Builder.app do
         | 
| 22 | 
            +
              #    use Rack::CommonLogger
         | 
| 23 | 
            +
              #    run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['OK']] }
         | 
| 24 | 
            +
              #  end
         | 
| 25 | 
            +
              #
         | 
| 26 | 
            +
              #  run app
         | 
| 27 | 
            +
              #
         | 
| 28 | 
            +
              # +use+ adds middleware to the stack, +run+ dispatches to an application.
         | 
| 29 | 
            +
              # You can use +map+ to construct a Rack::URLMap in a convenient way.
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              class Builder
         | 
| 32 | 
            +
                def self.parse_file(config, opts = Server::Options.new)
         | 
| 33 | 
            +
                  options = {}
         | 
| 34 | 
            +
                  if config =~ /\.ru$/
         | 
| 35 | 
            +
                    cfgfile = ::File.read(config)
         | 
| 36 | 
            +
                    if cfgfile[/^#\\(.*)/] && opts
         | 
| 37 | 
            +
                      options = opts.parse! $1.split(/\s+/)
         | 
| 38 | 
            +
                    end
         | 
| 39 | 
            +
                    cfgfile.sub!(/^__END__\n.*\Z/m, '')
         | 
| 40 | 
            +
                    app = new_from_string cfgfile, config
         | 
| 41 | 
            +
                  else
         | 
| 42 | 
            +
                    require config
         | 
| 43 | 
            +
                    app = Object.const_get(::File.basename(config, '.rb').capitalize)
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                  [app, options]
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                def self.new_from_string(builder_script, file="(rackup)")
         | 
| 49 | 
            +
                  eval "Rack::Builder.new {\n" + builder_script + "\n}.to_app", TOPLEVEL_BINDING, file, 0
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def initialize(default_app = nil,&block)
         | 
| 53 | 
            +
                  @use = []
         | 
| 54 | 
            +
                  @map = nil
         | 
| 55 | 
            +
                  @run = default_app
         | 
| 56 | 
            +
                  @warmup = nil
         | 
| 57 | 
            +
                  instance_eval(&block) if block_given?
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                def self.app(default_app = nil, &block)
         | 
| 61 | 
            +
                  self.new(default_app, &block).to_app
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                # Specifies middleware to use in a stack.
         | 
| 65 | 
            +
                #
         | 
| 66 | 
            +
                #   class Middleware
         | 
| 67 | 
            +
                #     def initialize(app)
         | 
| 68 | 
            +
                #       @app = app
         | 
| 69 | 
            +
                #     end
         | 
| 70 | 
            +
                #
         | 
| 71 | 
            +
                #     def call(env)
         | 
| 72 | 
            +
                #       env["rack.some_header"] = "setting an example"
         | 
| 73 | 
            +
                #       @app.call(env)
         | 
| 74 | 
            +
                #     end
         | 
| 75 | 
            +
                #   end
         | 
| 76 | 
            +
                #
         | 
| 77 | 
            +
                #   use Middleware
         | 
| 78 | 
            +
                #   run lambda { |env| [200, { "Content-Type" => "text/plain" }, ["OK"]] }
         | 
| 79 | 
            +
                #
         | 
| 80 | 
            +
                # All requests through to this application will first be processed by the middleware class.
         | 
| 81 | 
            +
                # The +call+ method in this example sets an additional environment key which then can be
         | 
| 82 | 
            +
                # referenced in the application if required.
         | 
| 83 | 
            +
                def use(middleware, *args, &block)
         | 
| 84 | 
            +
                  if @map
         | 
| 85 | 
            +
                    mapping, @map = @map, nil
         | 
| 86 | 
            +
                    @use << proc { |app| generate_map app, mapping }
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
                  @use << proc { |app| middleware.new(app, *args, &block) }
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                # Takes an argument that is an object that responds to #call and returns a Rack response.
         | 
| 92 | 
            +
                # The simplest form of this is a lambda object:
         | 
| 93 | 
            +
                #
         | 
| 94 | 
            +
                #   run lambda { |env| [200, { "Content-Type" => "text/plain" }, ["OK"]] }
         | 
| 95 | 
            +
                #
         | 
| 96 | 
            +
                # However this could also be a class:
         | 
| 97 | 
            +
                #
         | 
| 98 | 
            +
                #   class Heartbeat
         | 
| 99 | 
            +
                #     def self.call(env)
         | 
| 100 | 
            +
                #      [200, { "Content-Type" => "text/plain" }, ["OK"]]
         | 
| 101 | 
            +
                #    end
         | 
| 102 | 
            +
                #   end
         | 
| 103 | 
            +
                #
         | 
| 104 | 
            +
                #   run Heartbeat
         | 
| 105 | 
            +
                def run(app)
         | 
| 106 | 
            +
                  @run = app
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                # Takes a lambda or block that is used to warm-up the application.
         | 
| 110 | 
            +
                #
         | 
| 111 | 
            +
                #   warmup do |app|
         | 
| 112 | 
            +
                #     client = Rack::MockRequest.new(app)
         | 
| 113 | 
            +
                #     client.get('/')
         | 
| 114 | 
            +
                #   end
         | 
| 115 | 
            +
                #
         | 
| 116 | 
            +
                #   use SomeMiddleware
         | 
| 117 | 
            +
                #   run MyApp
         | 
| 118 | 
            +
                def warmup(prc=nil, &block)
         | 
| 119 | 
            +
                  @warmup = prc || block
         | 
| 120 | 
            +
                end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                # Creates a route within the application.
         | 
| 123 | 
            +
                #
         | 
| 124 | 
            +
                #   Rack::Builder.app do
         | 
| 125 | 
            +
                #     map '/' do
         | 
| 126 | 
            +
                #       run Heartbeat
         | 
| 127 | 
            +
                #     end
         | 
| 128 | 
            +
                #   end
         | 
| 129 | 
            +
                #
         | 
| 130 | 
            +
                # The +use+ method can also be used here to specify middleware to run under a specific path:
         | 
| 131 | 
            +
                #
         | 
| 132 | 
            +
                #   Rack::Builder.app do
         | 
| 133 | 
            +
                #     map '/' do
         | 
| 134 | 
            +
                #       use Middleware
         | 
| 135 | 
            +
                #       run Heartbeat
         | 
| 136 | 
            +
                #     end
         | 
| 137 | 
            +
                #   end
         | 
| 138 | 
            +
                #
         | 
| 139 | 
            +
                # This example includes a piece of middleware which will run before requests hit +Heartbeat+.
         | 
| 140 | 
            +
                #
         | 
| 141 | 
            +
                def map(path, &block)
         | 
| 142 | 
            +
                  @map ||= {}
         | 
| 143 | 
            +
                  @map[path] = block
         | 
| 144 | 
            +
                end
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                def to_app
         | 
| 147 | 
            +
                  app = @map ? generate_map(@run, @map) : @run
         | 
| 148 | 
            +
                  fail "missing run or map statement" unless app
         | 
| 149 | 
            +
                  app = @use.reverse.inject(app) { |a,e| e[a] }
         | 
| 150 | 
            +
                  @warmup.call(app) if @warmup
         | 
| 151 | 
            +
                  app
         | 
| 152 | 
            +
                end
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                def call(env)
         | 
| 155 | 
            +
                  to_app.call(env)
         | 
| 156 | 
            +
                end
         | 
| 157 | 
            +
             | 
| 158 | 
            +
                private
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                def generate_map(default_app, mapping)
         | 
| 161 | 
            +
                  mapped = default_app ? {'/' => default_app} : {}
         | 
| 162 | 
            +
                  mapping.each { |r,b| mapped[r] = self.class.new(default_app, &b).to_app }
         | 
| 163 | 
            +
                  URLMap.new(mapped)
         | 
| 164 | 
            +
                end
         | 
| 165 | 
            +
              end
         | 
| 166 | 
            +
            end
         | 
    
        data/lib/rack/handler.rb
    ADDED
    
    | @@ -0,0 +1,63 @@ | |
| 1 | 
            +
            module Rack
         | 
| 2 | 
            +
              # *Handlers* connect web servers with Rack.
         | 
| 3 | 
            +
              #
         | 
| 4 | 
            +
              # Handlers usually are activated by calling <tt>MyHandler.run(myapp)</tt>.
         | 
| 5 | 
            +
              # A second optional hash can be passed to include server-specific
         | 
| 6 | 
            +
              # configuration.
         | 
| 7 | 
            +
              module Handler
         | 
| 8 | 
            +
                require_relative "handler/webrick"
         | 
| 9 | 
            +
                def self.get(server)
         | 
| 10 | 
            +
                  return unless server
         | 
| 11 | 
            +
                  server = server.to_s
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  unless @handlers.include? server
         | 
| 14 | 
            +
                    load_error = try_require("rack/handler", server)
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  if klass = @handlers[server]
         | 
| 18 | 
            +
                    klass.split("::").inject(Object) { |o, x| o.const_get(x) }
         | 
| 19 | 
            +
                  else
         | 
| 20 | 
            +
                    const_get(server)
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                rescue NameError => name_error
         | 
| 24 | 
            +
                  raise load_error || name_error
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def self.default(options = {})
         | 
| 28 | 
            +
                  # Guess.
         | 
| 29 | 
            +
                  if ENV.include?("RACK_HANDLER")
         | 
| 30 | 
            +
                    get(ENV["RACK_HANDLER"])
         | 
| 31 | 
            +
                  else
         | 
| 32 | 
            +
                    "webrick"
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                # Transforms server-name constants to their canonical form as filenames,
         | 
| 37 | 
            +
                # then tries to require them but silences the LoadError if not found
         | 
| 38 | 
            +
                #
         | 
| 39 | 
            +
                # Naming convention:
         | 
| 40 | 
            +
                #
         | 
| 41 | 
            +
                #   Foo # => 'foo'
         | 
| 42 | 
            +
                #   FooBar # => 'foo_bar.rb'
         | 
| 43 | 
            +
                #   FooBAR # => 'foobar.rb'
         | 
| 44 | 
            +
                #   FOObar # => 'foobar.rb'
         | 
| 45 | 
            +
                #   FOOBAR # => 'foobar.rb'
         | 
| 46 | 
            +
                #   FooBarBaz # => 'foo_bar_baz.rb'
         | 
| 47 | 
            +
                def self.try_require(prefix, const_name)
         | 
| 48 | 
            +
                  file = const_name.gsub(/^[A-Z]+/) { |pre| pre.downcase }.
         | 
| 49 | 
            +
                    gsub(/[A-Z]+[^A-Z]/, '_\&').downcase
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  require(::File.join(prefix, file))
         | 
| 52 | 
            +
                  nil
         | 
| 53 | 
            +
                rescue LoadError => error
         | 
| 54 | 
            +
                  error
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                def self.register(server, klass)
         | 
| 58 | 
            +
                  @handlers ||= {}
         | 
| 59 | 
            +
                  @handlers[server.to_s] = klass.to_s
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
                register "webrick", "Rack::Handler::WEBrick"
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
            end
         | 
| @@ -0,0 +1,120 @@ | |
| 1 | 
            +
            require 'webrick'
         | 
| 2 | 
            +
            require 'stringio'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            # This monkey patch allows for applications to perform their own chunking
         | 
| 5 | 
            +
            # through WEBrick::HTTPResponse if rack is set to true.
         | 
| 6 | 
            +
            class WEBrick::HTTPResponse
         | 
| 7 | 
            +
              attr_accessor :rack
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              alias _rack_setup_header setup_header
         | 
| 10 | 
            +
              def setup_header
         | 
| 11 | 
            +
                if rack && @header["transfer-encoding"] == "chunked"
         | 
| 12 | 
            +
                  @chunked = true
         | 
| 13 | 
            +
                  _rack_setup_header
         | 
| 14 | 
            +
                  @chunked = false
         | 
| 15 | 
            +
                else
         | 
| 16 | 
            +
                  _rack_setup_header
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            module Rack
         | 
| 22 | 
            +
              module Handler
         | 
| 23 | 
            +
                class WEBrick < ::WEBrick::HTTPServlet::AbstractServlet
         | 
| 24 | 
            +
                  def self.run(app, options={})
         | 
| 25 | 
            +
                    environment  = ENV["RACK_ENV"] || "development"
         | 
| 26 | 
            +
                    default_host = environment == "development" ? "localhost" : "0.0.0.0"
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    options[:BindAddress] = options.delete(:Host) || default_host
         | 
| 29 | 
            +
                    options[:Port] ||= 8080
         | 
| 30 | 
            +
                    options[:OutputBufferSize] = 5
         | 
| 31 | 
            +
                    @server = ::WEBrick::HTTPServer.new(options)
         | 
| 32 | 
            +
                    @server.mount "/", Rack::Handler::WEBrick, app
         | 
| 33 | 
            +
                    yield @server  if block_given?
         | 
| 34 | 
            +
                    @server.start
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  def self.valid_options
         | 
| 38 | 
            +
                    environment  = ENV["RACK_ENV"] || "development"
         | 
| 39 | 
            +
                    default_host = environment == "development" ? "localhost" : "0.0.0.0"
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                    {
         | 
| 42 | 
            +
                      "Host=HOST" => "Hostname to listen on (default: #{default_host})",
         | 
| 43 | 
            +
                      "Port=PORT" => "Port to listen on (default: 8080)",
         | 
| 44 | 
            +
                    }
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  def self.shutdown
         | 
| 48 | 
            +
                    @server.shutdown
         | 
| 49 | 
            +
                    @server = nil
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  def initialize(server, app)
         | 
| 53 | 
            +
                    super server
         | 
| 54 | 
            +
                    @app = app
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  def service(req, res)
         | 
| 58 | 
            +
                    res.rack = true
         | 
| 59 | 
            +
                    env = req.meta_vars
         | 
| 60 | 
            +
                    env.delete_if { |k, v| v.nil? }
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    rack_input = StringIO.new(req.body.to_s)
         | 
| 63 | 
            +
                    rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                    env.update({"rack.version" => Rack::VERSION,
         | 
| 66 | 
            +
                                 "rack.input" => rack_input,
         | 
| 67 | 
            +
                                 "rack.errors" => $stderr,
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                                 "rack.multithread" => true,
         | 
| 70 | 
            +
                                 "rack.multiprocess" => false,
         | 
| 71 | 
            +
                                 "rack.run_once" => false,
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                                 "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http",
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                                 "rack.hijack?" => true,
         | 
| 76 | 
            +
                                 "rack.hijack" => lambda { raise NotImplementedError, "only partial hijack is supported."},
         | 
| 77 | 
            +
                                 "rack.hijack_io" => nil,
         | 
| 78 | 
            +
                               })
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                    env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
         | 
| 81 | 
            +
                    env["QUERY_STRING"] ||= ""
         | 
| 82 | 
            +
                    unless env["PATH_INFO"] == ""
         | 
| 83 | 
            +
                      path, n = req.request_uri.path, env["SCRIPT_NAME"].length
         | 
| 84 | 
            +
                      env["PATH_INFO"] = path[n, path.length-n]
         | 
| 85 | 
            +
                    end
         | 
| 86 | 
            +
                    env["REQUEST_PATH"] ||= [env["SCRIPT_NAME"], env["PATH_INFO"]].join
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                    status, headers, body = @app.call(env)
         | 
| 89 | 
            +
                    begin
         | 
| 90 | 
            +
                      res.status = status.to_i
         | 
| 91 | 
            +
                      headers.each { |k, vs|
         | 
| 92 | 
            +
                        next if k.downcase == "rack.hijack"
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                        if k.downcase == "set-cookie"
         | 
| 95 | 
            +
                          res.cookies.concat vs.split("\n")
         | 
| 96 | 
            +
                        else
         | 
| 97 | 
            +
                          # Since WEBrick won't accept repeated headers,
         | 
| 98 | 
            +
                          # merge the values per RFC 1945 section 4.2.
         | 
| 99 | 
            +
                          res[k] = vs.split("\n").join(", ")
         | 
| 100 | 
            +
                        end
         | 
| 101 | 
            +
                      }
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                      io_lambda = headers["rack.hijack"]
         | 
| 104 | 
            +
                      if io_lambda
         | 
| 105 | 
            +
                        rd, wr = IO.pipe
         | 
| 106 | 
            +
                        res.body = rd
         | 
| 107 | 
            +
                        res.chunked = true
         | 
| 108 | 
            +
                        io_lambda.call wr
         | 
| 109 | 
            +
                      else
         | 
| 110 | 
            +
                        body.each { |part|
         | 
| 111 | 
            +
                          res.body << part
         | 
| 112 | 
            +
                        }
         | 
| 113 | 
            +
                      end
         | 
| 114 | 
            +
                    ensure
         | 
| 115 | 
            +
                      body.close  if body.respond_to? :close
         | 
| 116 | 
            +
                    end
         | 
| 117 | 
            +
                  end
         | 
| 118 | 
            +
                end
         | 
| 119 | 
            +
              end
         | 
| 120 | 
            +
            end
         | 
    
        data/lib/rack/mime.rb
    ADDED
    
    | @@ -0,0 +1,661 @@ | |
| 1 | 
            +
            module Rack
         | 
| 2 | 
            +
              module Mime
         | 
| 3 | 
            +
                # Returns String with mime type if found, otherwise use +fallback+.
         | 
| 4 | 
            +
                # +ext+ should be filename extension in the '.ext' format that
         | 
| 5 | 
            +
                #       File.extname(file) returns.
         | 
| 6 | 
            +
                # +fallback+ may be any object
         | 
| 7 | 
            +
                #
         | 
| 8 | 
            +
                # Also see the documentation for MIME_TYPES
         | 
| 9 | 
            +
                #
         | 
| 10 | 
            +
                # Usage:
         | 
| 11 | 
            +
                #     Rack::Mime.mime_type('.foo')
         | 
| 12 | 
            +
                #
         | 
| 13 | 
            +
                # This is a shortcut for:
         | 
| 14 | 
            +
                #     Rack::Mime::MIME_TYPES.fetch('.foo', 'application/octet-stream')
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                module_function def mime_type(ext, fallback='application/octet-stream')
         | 
| 17 | 
            +
                  MIME_TYPES.fetch(ext.to_s.downcase, fallback)
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                # Returns true if the given value is a mime match for the given mime match
         | 
| 21 | 
            +
                # specification, false otherwise.
         | 
| 22 | 
            +
                #
         | 
| 23 | 
            +
                #    Rack::Mime.match?('text/html', 'text/*') => true
         | 
| 24 | 
            +
                #    Rack::Mime.match?('text/plain', '*') => true
         | 
| 25 | 
            +
                #    Rack::Mime.match?('text/html', 'application/json') => false
         | 
| 26 | 
            +
                module_function def match?(value, matcher)
         | 
| 27 | 
            +
                  v1, v2 = value.split('/', 2)
         | 
| 28 | 
            +
                  m1, m2 = matcher.split('/', 2)
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  (m1 == '*' || v1 == m1) && (m2.nil? || m2 == '*' || m2 == v2)
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
             | 
| 34 | 
            +
                # List of most common mime-types, selected various sources
         | 
| 35 | 
            +
                # according to their usefulness in a webserving scope for Ruby
         | 
| 36 | 
            +
                # users.
         | 
| 37 | 
            +
                #
         | 
| 38 | 
            +
                # To amend this list with your local mime.types list you can use:
         | 
| 39 | 
            +
                #
         | 
| 40 | 
            +
                #     require 'webrick/httputils'
         | 
| 41 | 
            +
                #     list = WEBrick::HTTPUtils.load_mime_types('/etc/mime.types')
         | 
| 42 | 
            +
                #     Rack::Mime::MIME_TYPES.merge!(list)
         | 
| 43 | 
            +
                #
         | 
| 44 | 
            +
                # N.B. On Ubuntu the mime.types file does not include the leading period, so
         | 
| 45 | 
            +
                # users may need to modify the data before merging into the hash.
         | 
| 46 | 
            +
                #
         | 
| 47 | 
            +
                # To add the list mongrel provides, use:
         | 
| 48 | 
            +
                #
         | 
| 49 | 
            +
                #     require 'mongrel/handlers'
         | 
| 50 | 
            +
                #     Rack::Mime::MIME_TYPES.merge!(Mongrel::DirHandler::MIME_TYPES)
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                MIME_TYPES = {
         | 
| 53 | 
            +
                  ".123"       => "application/vnd.lotus-1-2-3",
         | 
| 54 | 
            +
                  ".3dml"      => "text/vnd.in3d.3dml",
         | 
| 55 | 
            +
                  ".3g2"       => "video/3gpp2",
         | 
| 56 | 
            +
                  ".3gp"       => "video/3gpp",
         | 
| 57 | 
            +
                  ".a"         => "application/octet-stream",
         | 
| 58 | 
            +
                  ".acc"       => "application/vnd.americandynamics.acc",
         | 
| 59 | 
            +
                  ".ace"       => "application/x-ace-compressed",
         | 
| 60 | 
            +
                  ".acu"       => "application/vnd.acucobol",
         | 
| 61 | 
            +
                  ".aep"       => "application/vnd.audiograph",
         | 
| 62 | 
            +
                  ".afp"       => "application/vnd.ibm.modcap",
         | 
| 63 | 
            +
                  ".ai"        => "application/postscript",
         | 
| 64 | 
            +
                  ".aif"       => "audio/x-aiff",
         | 
| 65 | 
            +
                  ".aiff"      => "audio/x-aiff",
         | 
| 66 | 
            +
                  ".ami"       => "application/vnd.amiga.ami",
         | 
| 67 | 
            +
                  ".appcache"  => "text/cache-manifest",
         | 
| 68 | 
            +
                  ".apr"       => "application/vnd.lotus-approach",
         | 
| 69 | 
            +
                  ".asc"       => "application/pgp-signature",
         | 
| 70 | 
            +
                  ".asf"       => "video/x-ms-asf",
         | 
| 71 | 
            +
                  ".asm"       => "text/x-asm",
         | 
| 72 | 
            +
                  ".aso"       => "application/vnd.accpac.simply.aso",
         | 
| 73 | 
            +
                  ".asx"       => "video/x-ms-asf",
         | 
| 74 | 
            +
                  ".atc"       => "application/vnd.acucorp",
         | 
| 75 | 
            +
                  ".atom"      => "application/atom+xml",
         | 
| 76 | 
            +
                  ".atomcat"   => "application/atomcat+xml",
         | 
| 77 | 
            +
                  ".atomsvc"   => "application/atomsvc+xml",
         | 
| 78 | 
            +
                  ".atx"       => "application/vnd.antix.game-component",
         | 
| 79 | 
            +
                  ".au"        => "audio/basic",
         | 
| 80 | 
            +
                  ".avi"       => "video/x-msvideo",
         | 
| 81 | 
            +
                  ".bat"       => "application/x-msdownload",
         | 
| 82 | 
            +
                  ".bcpio"     => "application/x-bcpio",
         | 
| 83 | 
            +
                  ".bdm"       => "application/vnd.syncml.dm+wbxml",
         | 
| 84 | 
            +
                  ".bh2"       => "application/vnd.fujitsu.oasysprs",
         | 
| 85 | 
            +
                  ".bin"       => "application/octet-stream",
         | 
| 86 | 
            +
                  ".bmi"       => "application/vnd.bmi",
         | 
| 87 | 
            +
                  ".bmp"       => "image/bmp",
         | 
| 88 | 
            +
                  ".box"       => "application/vnd.previewsystems.box",
         | 
| 89 | 
            +
                  ".btif"      => "image/prs.btif",
         | 
| 90 | 
            +
                  ".bz"        => "application/x-bzip",
         | 
| 91 | 
            +
                  ".bz2"       => "application/x-bzip2",
         | 
| 92 | 
            +
                  ".c"         => "text/x-c",
         | 
| 93 | 
            +
                  ".c4g"       => "application/vnd.clonk.c4group",
         | 
| 94 | 
            +
                  ".cab"       => "application/vnd.ms-cab-compressed",
         | 
| 95 | 
            +
                  ".cc"        => "text/x-c",
         | 
| 96 | 
            +
                  ".ccxml"     => "application/ccxml+xml",
         | 
| 97 | 
            +
                  ".cdbcmsg"   => "application/vnd.contact.cmsg",
         | 
| 98 | 
            +
                  ".cdkey"     => "application/vnd.mediastation.cdkey",
         | 
| 99 | 
            +
                  ".cdx"       => "chemical/x-cdx",
         | 
| 100 | 
            +
                  ".cdxml"     => "application/vnd.chemdraw+xml",
         | 
| 101 | 
            +
                  ".cdy"       => "application/vnd.cinderella",
         | 
| 102 | 
            +
                  ".cer"       => "application/pkix-cert",
         | 
| 103 | 
            +
                  ".cgm"       => "image/cgm",
         | 
| 104 | 
            +
                  ".chat"      => "application/x-chat",
         | 
| 105 | 
            +
                  ".chm"       => "application/vnd.ms-htmlhelp",
         | 
| 106 | 
            +
                  ".chrt"      => "application/vnd.kde.kchart",
         | 
| 107 | 
            +
                  ".cif"       => "chemical/x-cif",
         | 
| 108 | 
            +
                  ".cii"       => "application/vnd.anser-web-certificate-issue-initiation",
         | 
| 109 | 
            +
                  ".cil"       => "application/vnd.ms-artgalry",
         | 
| 110 | 
            +
                  ".cla"       => "application/vnd.claymore",
         | 
| 111 | 
            +
                  ".class"     => "application/octet-stream",
         | 
| 112 | 
            +
                  ".clkk"      => "application/vnd.crick.clicker.keyboard",
         | 
| 113 | 
            +
                  ".clkp"      => "application/vnd.crick.clicker.palette",
         | 
| 114 | 
            +
                  ".clkt"      => "application/vnd.crick.clicker.template",
         | 
| 115 | 
            +
                  ".clkw"      => "application/vnd.crick.clicker.wordbank",
         | 
| 116 | 
            +
                  ".clkx"      => "application/vnd.crick.clicker",
         | 
| 117 | 
            +
                  ".clp"       => "application/x-msclip",
         | 
| 118 | 
            +
                  ".cmc"       => "application/vnd.cosmocaller",
         | 
| 119 | 
            +
                  ".cmdf"      => "chemical/x-cmdf",
         | 
| 120 | 
            +
                  ".cml"       => "chemical/x-cml",
         | 
| 121 | 
            +
                  ".cmp"       => "application/vnd.yellowriver-custom-menu",
         | 
| 122 | 
            +
                  ".cmx"       => "image/x-cmx",
         | 
| 123 | 
            +
                  ".com"       => "application/x-msdownload",
         | 
| 124 | 
            +
                  ".conf"      => "text/plain",
         | 
| 125 | 
            +
                  ".cpio"      => "application/x-cpio",
         | 
| 126 | 
            +
                  ".cpp"       => "text/x-c",
         | 
| 127 | 
            +
                  ".cpt"       => "application/mac-compactpro",
         | 
| 128 | 
            +
                  ".crd"       => "application/x-mscardfile",
         | 
| 129 | 
            +
                  ".crl"       => "application/pkix-crl",
         | 
| 130 | 
            +
                  ".crt"       => "application/x-x509-ca-cert",
         | 
| 131 | 
            +
                  ".csh"       => "application/x-csh",
         | 
| 132 | 
            +
                  ".csml"      => "chemical/x-csml",
         | 
| 133 | 
            +
                  ".csp"       => "application/vnd.commonspace",
         | 
| 134 | 
            +
                  ".css"       => "text/css",
         | 
| 135 | 
            +
                  ".csv"       => "text/csv",
         | 
| 136 | 
            +
                  ".curl"      => "application/vnd.curl",
         | 
| 137 | 
            +
                  ".cww"       => "application/prs.cww",
         | 
| 138 | 
            +
                  ".cxx"       => "text/x-c",
         | 
| 139 | 
            +
                  ".daf"       => "application/vnd.mobius.daf",
         | 
| 140 | 
            +
                  ".davmount"  => "application/davmount+xml",
         | 
| 141 | 
            +
                  ".dcr"       => "application/x-director",
         | 
| 142 | 
            +
                  ".dd2"       => "application/vnd.oma.dd2+xml",
         | 
| 143 | 
            +
                  ".ddd"       => "application/vnd.fujixerox.ddd",
         | 
| 144 | 
            +
                  ".deb"       => "application/x-debian-package",
         | 
| 145 | 
            +
                  ".der"       => "application/x-x509-ca-cert",
         | 
| 146 | 
            +
                  ".dfac"      => "application/vnd.dreamfactory",
         | 
| 147 | 
            +
                  ".diff"      => "text/x-diff",
         | 
| 148 | 
            +
                  ".dis"       => "application/vnd.mobius.dis",
         | 
| 149 | 
            +
                  ".djv"       => "image/vnd.djvu",
         | 
| 150 | 
            +
                  ".djvu"      => "image/vnd.djvu",
         | 
| 151 | 
            +
                  ".dll"       => "application/x-msdownload",
         | 
| 152 | 
            +
                  ".dmg"       => "application/octet-stream",
         | 
| 153 | 
            +
                  ".dna"       => "application/vnd.dna",
         | 
| 154 | 
            +
                  ".doc"       => "application/msword",
         | 
| 155 | 
            +
                  ".docx"      => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
         | 
| 156 | 
            +
                  ".dot"       => "application/msword",
         | 
| 157 | 
            +
                  ".dp"        => "application/vnd.osgi.dp",
         | 
| 158 | 
            +
                  ".dpg"       => "application/vnd.dpgraph",
         | 
| 159 | 
            +
                  ".dsc"       => "text/prs.lines.tag",
         | 
| 160 | 
            +
                  ".dtd"       => "application/xml-dtd",
         | 
| 161 | 
            +
                  ".dts"       => "audio/vnd.dts",
         | 
| 162 | 
            +
                  ".dtshd"     => "audio/vnd.dts.hd",
         | 
| 163 | 
            +
                  ".dv"        => "video/x-dv",
         | 
| 164 | 
            +
                  ".dvi"       => "application/x-dvi",
         | 
| 165 | 
            +
                  ".dwf"       => "model/vnd.dwf",
         | 
| 166 | 
            +
                  ".dwg"       => "image/vnd.dwg",
         | 
| 167 | 
            +
                  ".dxf"       => "image/vnd.dxf",
         | 
| 168 | 
            +
                  ".dxp"       => "application/vnd.spotfire.dxp",
         | 
| 169 | 
            +
                  ".ear"       => "application/java-archive",
         | 
| 170 | 
            +
                  ".ecelp4800" => "audio/vnd.nuera.ecelp4800",
         | 
| 171 | 
            +
                  ".ecelp7470" => "audio/vnd.nuera.ecelp7470",
         | 
| 172 | 
            +
                  ".ecelp9600" => "audio/vnd.nuera.ecelp9600",
         | 
| 173 | 
            +
                  ".ecma"      => "application/ecmascript",
         | 
| 174 | 
            +
                  ".edm"       => "application/vnd.novadigm.edm",
         | 
| 175 | 
            +
                  ".edx"       => "application/vnd.novadigm.edx",
         | 
| 176 | 
            +
                  ".efif"      => "application/vnd.picsel",
         | 
| 177 | 
            +
                  ".ei6"       => "application/vnd.pg.osasli",
         | 
| 178 | 
            +
                  ".eml"       => "message/rfc822",
         | 
| 179 | 
            +
                  ".eol"       => "audio/vnd.digital-winds",
         | 
| 180 | 
            +
                  ".eot"       => "application/vnd.ms-fontobject",
         | 
| 181 | 
            +
                  ".eps"       => "application/postscript",
         | 
| 182 | 
            +
                  ".es3"       => "application/vnd.eszigno3+xml",
         | 
| 183 | 
            +
                  ".esf"       => "application/vnd.epson.esf",
         | 
| 184 | 
            +
                  ".etx"       => "text/x-setext",
         | 
| 185 | 
            +
                  ".exe"       => "application/x-msdownload",
         | 
| 186 | 
            +
                  ".ext"       => "application/vnd.novadigm.ext",
         | 
| 187 | 
            +
                  ".ez"        => "application/andrew-inset",
         | 
| 188 | 
            +
                  ".ez2"       => "application/vnd.ezpix-album",
         | 
| 189 | 
            +
                  ".ez3"       => "application/vnd.ezpix-package",
         | 
| 190 | 
            +
                  ".f"         => "text/x-fortran",
         | 
| 191 | 
            +
                  ".f77"       => "text/x-fortran",
         | 
| 192 | 
            +
                  ".f90"       => "text/x-fortran",
         | 
| 193 | 
            +
                  ".fbs"       => "image/vnd.fastbidsheet",
         | 
| 194 | 
            +
                  ".fdf"       => "application/vnd.fdf",
         | 
| 195 | 
            +
                  ".fe_launch" => "application/vnd.denovo.fcselayout-link",
         | 
| 196 | 
            +
                  ".fg5"       => "application/vnd.fujitsu.oasysgp",
         | 
| 197 | 
            +
                  ".fli"       => "video/x-fli",
         | 
| 198 | 
            +
                  ".flo"       => "application/vnd.micrografx.flo",
         | 
| 199 | 
            +
                  ".flv"       => "video/x-flv",
         | 
| 200 | 
            +
                  ".flw"       => "application/vnd.kde.kivio",
         | 
| 201 | 
            +
                  ".flx"       => "text/vnd.fmi.flexstor",
         | 
| 202 | 
            +
                  ".fly"       => "text/vnd.fly",
         | 
| 203 | 
            +
                  ".fm"        => "application/vnd.framemaker",
         | 
| 204 | 
            +
                  ".fnc"       => "application/vnd.frogans.fnc",
         | 
| 205 | 
            +
                  ".for"       => "text/x-fortran",
         | 
| 206 | 
            +
                  ".fpx"       => "image/vnd.fpx",
         | 
| 207 | 
            +
                  ".fsc"       => "application/vnd.fsc.weblaunch",
         | 
| 208 | 
            +
                  ".fst"       => "image/vnd.fst",
         | 
| 209 | 
            +
                  ".ftc"       => "application/vnd.fluxtime.clip",
         | 
| 210 | 
            +
                  ".fti"       => "application/vnd.anser-web-funds-transfer-initiation",
         | 
| 211 | 
            +
                  ".fvt"       => "video/vnd.fvt",
         | 
| 212 | 
            +
                  ".fzs"       => "application/vnd.fuzzysheet",
         | 
| 213 | 
            +
                  ".g3"        => "image/g3fax",
         | 
| 214 | 
            +
                  ".gac"       => "application/vnd.groove-account",
         | 
| 215 | 
            +
                  ".gdl"       => "model/vnd.gdl",
         | 
| 216 | 
            +
                  ".gem"       => "application/octet-stream",
         | 
| 217 | 
            +
                  ".gemspec"   => "text/x-script.ruby",
         | 
| 218 | 
            +
                  ".ghf"       => "application/vnd.groove-help",
         | 
| 219 | 
            +
                  ".gif"       => "image/gif",
         | 
| 220 | 
            +
                  ".gim"       => "application/vnd.groove-identity-message",
         | 
| 221 | 
            +
                  ".gmx"       => "application/vnd.gmx",
         | 
| 222 | 
            +
                  ".gph"       => "application/vnd.flographit",
         | 
| 223 | 
            +
                  ".gqf"       => "application/vnd.grafeq",
         | 
| 224 | 
            +
                  ".gram"      => "application/srgs",
         | 
| 225 | 
            +
                  ".grv"       => "application/vnd.groove-injector",
         | 
| 226 | 
            +
                  ".grxml"     => "application/srgs+xml",
         | 
| 227 | 
            +
                  ".gtar"      => "application/x-gtar",
         | 
| 228 | 
            +
                  ".gtm"       => "application/vnd.groove-tool-message",
         | 
| 229 | 
            +
                  ".gtw"       => "model/vnd.gtw",
         | 
| 230 | 
            +
                  ".gv"        => "text/vnd.graphviz",
         | 
| 231 | 
            +
                  ".gz"        => "application/x-gzip",
         | 
| 232 | 
            +
                  ".h"         => "text/x-c",
         | 
| 233 | 
            +
                  ".h261"      => "video/h261",
         | 
| 234 | 
            +
                  ".h263"      => "video/h263",
         | 
| 235 | 
            +
                  ".h264"      => "video/h264",
         | 
| 236 | 
            +
                  ".hbci"      => "application/vnd.hbci",
         | 
| 237 | 
            +
                  ".hdf"       => "application/x-hdf",
         | 
| 238 | 
            +
                  ".hh"        => "text/x-c",
         | 
| 239 | 
            +
                  ".hlp"       => "application/winhlp",
         | 
| 240 | 
            +
                  ".hpgl"      => "application/vnd.hp-hpgl",
         | 
| 241 | 
            +
                  ".hpid"      => "application/vnd.hp-hpid",
         | 
| 242 | 
            +
                  ".hps"       => "application/vnd.hp-hps",
         | 
| 243 | 
            +
                  ".hqx"       => "application/mac-binhex40",
         | 
| 244 | 
            +
                  ".htc"       => "text/x-component",
         | 
| 245 | 
            +
                  ".htke"      => "application/vnd.kenameaapp",
         | 
| 246 | 
            +
                  ".htm"       => "text/html",
         | 
| 247 | 
            +
                  ".html"      => "text/html",
         | 
| 248 | 
            +
                  ".hvd"       => "application/vnd.yamaha.hv-dic",
         | 
| 249 | 
            +
                  ".hvp"       => "application/vnd.yamaha.hv-voice",
         | 
| 250 | 
            +
                  ".hvs"       => "application/vnd.yamaha.hv-script",
         | 
| 251 | 
            +
                  ".icc"       => "application/vnd.iccprofile",
         | 
| 252 | 
            +
                  ".ice"       => "x-conference/x-cooltalk",
         | 
| 253 | 
            +
                  ".ico"       => "image/vnd.microsoft.icon",
         | 
| 254 | 
            +
                  ".ics"       => "text/calendar",
         | 
| 255 | 
            +
                  ".ief"       => "image/ief",
         | 
| 256 | 
            +
                  ".ifb"       => "text/calendar",
         | 
| 257 | 
            +
                  ".ifm"       => "application/vnd.shana.informed.formdata",
         | 
| 258 | 
            +
                  ".igl"       => "application/vnd.igloader",
         | 
| 259 | 
            +
                  ".igs"       => "model/iges",
         | 
| 260 | 
            +
                  ".igx"       => "application/vnd.micrografx.igx",
         | 
| 261 | 
            +
                  ".iif"       => "application/vnd.shana.informed.interchange",
         | 
| 262 | 
            +
                  ".imp"       => "application/vnd.accpac.simply.imp",
         | 
| 263 | 
            +
                  ".ims"       => "application/vnd.ms-ims",
         | 
| 264 | 
            +
                  ".ipk"       => "application/vnd.shana.informed.package",
         | 
| 265 | 
            +
                  ".irm"       => "application/vnd.ibm.rights-management",
         | 
| 266 | 
            +
                  ".irp"       => "application/vnd.irepository.package+xml",
         | 
| 267 | 
            +
                  ".iso"       => "application/octet-stream",
         | 
| 268 | 
            +
                  ".itp"       => "application/vnd.shana.informed.formtemplate",
         | 
| 269 | 
            +
                  ".ivp"       => "application/vnd.immervision-ivp",
         | 
| 270 | 
            +
                  ".ivu"       => "application/vnd.immervision-ivu",
         | 
| 271 | 
            +
                  ".jad"       => "text/vnd.sun.j2me.app-descriptor",
         | 
| 272 | 
            +
                  ".jam"       => "application/vnd.jam",
         | 
| 273 | 
            +
                  ".jar"       => "application/java-archive",
         | 
| 274 | 
            +
                  ".java"      => "text/x-java-source",
         | 
| 275 | 
            +
                  ".jisp"      => "application/vnd.jisp",
         | 
| 276 | 
            +
                  ".jlt"       => "application/vnd.hp-jlyt",
         | 
| 277 | 
            +
                  ".jnlp"      => "application/x-java-jnlp-file",
         | 
| 278 | 
            +
                  ".joda"      => "application/vnd.joost.joda-archive",
         | 
| 279 | 
            +
                  ".jp2"       => "image/jp2",
         | 
| 280 | 
            +
                  ".jpeg"      => "image/jpeg",
         | 
| 281 | 
            +
                  ".jpg"       => "image/jpeg",
         | 
| 282 | 
            +
                  ".jpgv"      => "video/jpeg",
         | 
| 283 | 
            +
                  ".jpm"       => "video/jpm",
         | 
| 284 | 
            +
                  ".js"        => "application/javascript",
         | 
| 285 | 
            +
                  ".json"      => "application/json",
         | 
| 286 | 
            +
                  ".karbon"    => "application/vnd.kde.karbon",
         | 
| 287 | 
            +
                  ".kfo"       => "application/vnd.kde.kformula",
         | 
| 288 | 
            +
                  ".kia"       => "application/vnd.kidspiration",
         | 
| 289 | 
            +
                  ".kml"       => "application/vnd.google-earth.kml+xml",
         | 
| 290 | 
            +
                  ".kmz"       => "application/vnd.google-earth.kmz",
         | 
| 291 | 
            +
                  ".kne"       => "application/vnd.kinar",
         | 
| 292 | 
            +
                  ".kon"       => "application/vnd.kde.kontour",
         | 
| 293 | 
            +
                  ".kpr"       => "application/vnd.kde.kpresenter",
         | 
| 294 | 
            +
                  ".ksp"       => "application/vnd.kde.kspread",
         | 
| 295 | 
            +
                  ".ktz"       => "application/vnd.kahootz",
         | 
| 296 | 
            +
                  ".kwd"       => "application/vnd.kde.kword",
         | 
| 297 | 
            +
                  ".latex"     => "application/x-latex",
         | 
| 298 | 
            +
                  ".lbd"       => "application/vnd.llamagraphics.life-balance.desktop",
         | 
| 299 | 
            +
                  ".lbe"       => "application/vnd.llamagraphics.life-balance.exchange+xml",
         | 
| 300 | 
            +
                  ".les"       => "application/vnd.hhe.lesson-player",
         | 
| 301 | 
            +
                  ".link66"    => "application/vnd.route66.link66+xml",
         | 
| 302 | 
            +
                  ".log"       => "text/plain",
         | 
| 303 | 
            +
                  ".lostxml"   => "application/lost+xml",
         | 
| 304 | 
            +
                  ".lrm"       => "application/vnd.ms-lrm",
         | 
| 305 | 
            +
                  ".ltf"       => "application/vnd.frogans.ltf",
         | 
| 306 | 
            +
                  ".lvp"       => "audio/vnd.lucent.voice",
         | 
| 307 | 
            +
                  ".lwp"       => "application/vnd.lotus-wordpro",
         | 
| 308 | 
            +
                  ".m3u"       => "audio/x-mpegurl",
         | 
| 309 | 
            +
                  ".m4a"       => "audio/mp4a-latm",
         | 
| 310 | 
            +
                  ".m4v"       => "video/mp4",
         | 
| 311 | 
            +
                  ".ma"        => "application/mathematica",
         | 
| 312 | 
            +
                  ".mag"       => "application/vnd.ecowin.chart",
         | 
| 313 | 
            +
                  ".man"       => "text/troff",
         | 
| 314 | 
            +
                  ".manifest"  => "text/cache-manifest",
         | 
| 315 | 
            +
                  ".mathml"    => "application/mathml+xml",
         | 
| 316 | 
            +
                  ".mbk"       => "application/vnd.mobius.mbk",
         | 
| 317 | 
            +
                  ".mbox"      => "application/mbox",
         | 
| 318 | 
            +
                  ".mc1"       => "application/vnd.medcalcdata",
         | 
| 319 | 
            +
                  ".mcd"       => "application/vnd.mcd",
         | 
| 320 | 
            +
                  ".mdb"       => "application/x-msaccess",
         | 
| 321 | 
            +
                  ".mdi"       => "image/vnd.ms-modi",
         | 
| 322 | 
            +
                  ".mdoc"      => "text/troff",
         | 
| 323 | 
            +
                  ".me"        => "text/troff",
         | 
| 324 | 
            +
                  ".mfm"       => "application/vnd.mfmp",
         | 
| 325 | 
            +
                  ".mgz"       => "application/vnd.proteus.magazine",
         | 
| 326 | 
            +
                  ".mid"       => "audio/midi",
         | 
| 327 | 
            +
                  ".midi"      => "audio/midi",
         | 
| 328 | 
            +
                  ".mif"       => "application/vnd.mif",
         | 
| 329 | 
            +
                  ".mime"      => "message/rfc822",
         | 
| 330 | 
            +
                  ".mj2"       => "video/mj2",
         | 
| 331 | 
            +
                  ".mlp"       => "application/vnd.dolby.mlp",
         | 
| 332 | 
            +
                  ".mmd"       => "application/vnd.chipnuts.karaoke-mmd",
         | 
| 333 | 
            +
                  ".mmf"       => "application/vnd.smaf",
         | 
| 334 | 
            +
                  ".mml"       => "application/mathml+xml",
         | 
| 335 | 
            +
                  ".mmr"       => "image/vnd.fujixerox.edmics-mmr",
         | 
| 336 | 
            +
                  ".mng"       => "video/x-mng",
         | 
| 337 | 
            +
                  ".mny"       => "application/x-msmoney",
         | 
| 338 | 
            +
                  ".mov"       => "video/quicktime",
         | 
| 339 | 
            +
                  ".movie"     => "video/x-sgi-movie",
         | 
| 340 | 
            +
                  ".mp3"       => "audio/mpeg",
         | 
| 341 | 
            +
                  ".mp4"       => "video/mp4",
         | 
| 342 | 
            +
                  ".mp4a"      => "audio/mp4",
         | 
| 343 | 
            +
                  ".mp4s"      => "application/mp4",
         | 
| 344 | 
            +
                  ".mp4v"      => "video/mp4",
         | 
| 345 | 
            +
                  ".mpc"       => "application/vnd.mophun.certificate",
         | 
| 346 | 
            +
                  ".mpeg"      => "video/mpeg",
         | 
| 347 | 
            +
                  ".mpg"       => "video/mpeg",
         | 
| 348 | 
            +
                  ".mpga"      => "audio/mpeg",
         | 
| 349 | 
            +
                  ".mpkg"      => "application/vnd.apple.installer+xml",
         | 
| 350 | 
            +
                  ".mpm"       => "application/vnd.blueice.multipass",
         | 
| 351 | 
            +
                  ".mpn"       => "application/vnd.mophun.application",
         | 
| 352 | 
            +
                  ".mpp"       => "application/vnd.ms-project",
         | 
| 353 | 
            +
                  ".mpy"       => "application/vnd.ibm.minipay",
         | 
| 354 | 
            +
                  ".mqy"       => "application/vnd.mobius.mqy",
         | 
| 355 | 
            +
                  ".mrc"       => "application/marc",
         | 
| 356 | 
            +
                  ".ms"        => "text/troff",
         | 
| 357 | 
            +
                  ".mscml"     => "application/mediaservercontrol+xml",
         | 
| 358 | 
            +
                  ".mseq"      => "application/vnd.mseq",
         | 
| 359 | 
            +
                  ".msf"       => "application/vnd.epson.msf",
         | 
| 360 | 
            +
                  ".msh"       => "model/mesh",
         | 
| 361 | 
            +
                  ".msi"       => "application/x-msdownload",
         | 
| 362 | 
            +
                  ".msl"       => "application/vnd.mobius.msl",
         | 
| 363 | 
            +
                  ".msty"      => "application/vnd.muvee.style",
         | 
| 364 | 
            +
                  ".mts"       => "model/vnd.mts",
         | 
| 365 | 
            +
                  ".mus"       => "application/vnd.musician",
         | 
| 366 | 
            +
                  ".mvb"       => "application/x-msmediaview",
         | 
| 367 | 
            +
                  ".mwf"       => "application/vnd.mfer",
         | 
| 368 | 
            +
                  ".mxf"       => "application/mxf",
         | 
| 369 | 
            +
                  ".mxl"       => "application/vnd.recordare.musicxml",
         | 
| 370 | 
            +
                  ".mxml"      => "application/xv+xml",
         | 
| 371 | 
            +
                  ".mxs"       => "application/vnd.triscape.mxs",
         | 
| 372 | 
            +
                  ".mxu"       => "video/vnd.mpegurl",
         | 
| 373 | 
            +
                  ".n"         => "application/vnd.nokia.n-gage.symbian.install",
         | 
| 374 | 
            +
                  ".nc"        => "application/x-netcdf",
         | 
| 375 | 
            +
                  ".ngdat"     => "application/vnd.nokia.n-gage.data",
         | 
| 376 | 
            +
                  ".nlu"       => "application/vnd.neurolanguage.nlu",
         | 
| 377 | 
            +
                  ".nml"       => "application/vnd.enliven",
         | 
| 378 | 
            +
                  ".nnd"       => "application/vnd.noblenet-directory",
         | 
| 379 | 
            +
                  ".nns"       => "application/vnd.noblenet-sealer",
         | 
| 380 | 
            +
                  ".nnw"       => "application/vnd.noblenet-web",
         | 
| 381 | 
            +
                  ".npx"       => "image/vnd.net-fpx",
         | 
| 382 | 
            +
                  ".nsf"       => "application/vnd.lotus-notes",
         | 
| 383 | 
            +
                  ".oa2"       => "application/vnd.fujitsu.oasys2",
         | 
| 384 | 
            +
                  ".oa3"       => "application/vnd.fujitsu.oasys3",
         | 
| 385 | 
            +
                  ".oas"       => "application/vnd.fujitsu.oasys",
         | 
| 386 | 
            +
                  ".obd"       => "application/x-msbinder",
         | 
| 387 | 
            +
                  ".oda"       => "application/oda",
         | 
| 388 | 
            +
                  ".odc"       => "application/vnd.oasis.opendocument.chart",
         | 
| 389 | 
            +
                  ".odf"       => "application/vnd.oasis.opendocument.formula",
         | 
| 390 | 
            +
                  ".odg"       => "application/vnd.oasis.opendocument.graphics",
         | 
| 391 | 
            +
                  ".odi"       => "application/vnd.oasis.opendocument.image",
         | 
| 392 | 
            +
                  ".odp"       => "application/vnd.oasis.opendocument.presentation",
         | 
| 393 | 
            +
                  ".ods"       => "application/vnd.oasis.opendocument.spreadsheet",
         | 
| 394 | 
            +
                  ".odt"       => "application/vnd.oasis.opendocument.text",
         | 
| 395 | 
            +
                  ".oga"       => "audio/ogg",
         | 
| 396 | 
            +
                  ".ogg"       => "application/ogg",
         | 
| 397 | 
            +
                  ".ogv"       => "video/ogg",
         | 
| 398 | 
            +
                  ".ogx"       => "application/ogg",
         | 
| 399 | 
            +
                  ".org"       => "application/vnd.lotus-organizer",
         | 
| 400 | 
            +
                  ".otc"       => "application/vnd.oasis.opendocument.chart-template",
         | 
| 401 | 
            +
                  ".otf"       => "application/vnd.oasis.opendocument.formula-template",
         | 
| 402 | 
            +
                  ".otg"       => "application/vnd.oasis.opendocument.graphics-template",
         | 
| 403 | 
            +
                  ".oth"       => "application/vnd.oasis.opendocument.text-web",
         | 
| 404 | 
            +
                  ".oti"       => "application/vnd.oasis.opendocument.image-template",
         | 
| 405 | 
            +
                  ".otm"       => "application/vnd.oasis.opendocument.text-master",
         | 
| 406 | 
            +
                  ".ots"       => "application/vnd.oasis.opendocument.spreadsheet-template",
         | 
| 407 | 
            +
                  ".ott"       => "application/vnd.oasis.opendocument.text-template",
         | 
| 408 | 
            +
                  ".oxt"       => "application/vnd.openofficeorg.extension",
         | 
| 409 | 
            +
                  ".p"         => "text/x-pascal",
         | 
| 410 | 
            +
                  ".p10"       => "application/pkcs10",
         | 
| 411 | 
            +
                  ".p12"       => "application/x-pkcs12",
         | 
| 412 | 
            +
                  ".p7b"       => "application/x-pkcs7-certificates",
         | 
| 413 | 
            +
                  ".p7m"       => "application/pkcs7-mime",
         | 
| 414 | 
            +
                  ".p7r"       => "application/x-pkcs7-certreqresp",
         | 
| 415 | 
            +
                  ".p7s"       => "application/pkcs7-signature",
         | 
| 416 | 
            +
                  ".pas"       => "text/x-pascal",
         | 
| 417 | 
            +
                  ".pbd"       => "application/vnd.powerbuilder6",
         | 
| 418 | 
            +
                  ".pbm"       => "image/x-portable-bitmap",
         | 
| 419 | 
            +
                  ".pcl"       => "application/vnd.hp-pcl",
         | 
| 420 | 
            +
                  ".pclxl"     => "application/vnd.hp-pclxl",
         | 
| 421 | 
            +
                  ".pcx"       => "image/x-pcx",
         | 
| 422 | 
            +
                  ".pdb"       => "chemical/x-pdb",
         | 
| 423 | 
            +
                  ".pdf"       => "application/pdf",
         | 
| 424 | 
            +
                  ".pem"       => "application/x-x509-ca-cert",
         | 
| 425 | 
            +
                  ".pfr"       => "application/font-tdpfr",
         | 
| 426 | 
            +
                  ".pgm"       => "image/x-portable-graymap",
         | 
| 427 | 
            +
                  ".pgn"       => "application/x-chess-pgn",
         | 
| 428 | 
            +
                  ".pgp"       => "application/pgp-encrypted",
         | 
| 429 | 
            +
                  ".pic"       => "image/x-pict",
         | 
| 430 | 
            +
                  ".pict"      => "image/pict",
         | 
| 431 | 
            +
                  ".pkg"       => "application/octet-stream",
         | 
| 432 | 
            +
                  ".pki"       => "application/pkixcmp",
         | 
| 433 | 
            +
                  ".pkipath"   => "application/pkix-pkipath",
         | 
| 434 | 
            +
                  ".pl"        => "text/x-script.perl",
         | 
| 435 | 
            +
                  ".plb"       => "application/vnd.3gpp.pic-bw-large",
         | 
| 436 | 
            +
                  ".plc"       => "application/vnd.mobius.plc",
         | 
| 437 | 
            +
                  ".plf"       => "application/vnd.pocketlearn",
         | 
| 438 | 
            +
                  ".pls"       => "application/pls+xml",
         | 
| 439 | 
            +
                  ".pm"        => "text/x-script.perl-module",
         | 
| 440 | 
            +
                  ".pml"       => "application/vnd.ctc-posml",
         | 
| 441 | 
            +
                  ".png"       => "image/png",
         | 
| 442 | 
            +
                  ".pnm"       => "image/x-portable-anymap",
         | 
| 443 | 
            +
                  ".pntg"      => "image/x-macpaint",
         | 
| 444 | 
            +
                  ".portpkg"   => "application/vnd.macports.portpkg",
         | 
| 445 | 
            +
                  ".ppd"       => "application/vnd.cups-ppd",
         | 
| 446 | 
            +
                  ".ppm"       => "image/x-portable-pixmap",
         | 
| 447 | 
            +
                  ".pps"       => "application/vnd.ms-powerpoint",
         | 
| 448 | 
            +
                  ".ppt"       => "application/vnd.ms-powerpoint",
         | 
| 449 | 
            +
                  ".prc"       => "application/vnd.palm",
         | 
| 450 | 
            +
                  ".pre"       => "application/vnd.lotus-freelance",
         | 
| 451 | 
            +
                  ".prf"       => "application/pics-rules",
         | 
| 452 | 
            +
                  ".ps"        => "application/postscript",
         | 
| 453 | 
            +
                  ".psb"       => "application/vnd.3gpp.pic-bw-small",
         | 
| 454 | 
            +
                  ".psd"       => "image/vnd.adobe.photoshop",
         | 
| 455 | 
            +
                  ".ptid"      => "application/vnd.pvi.ptid1",
         | 
| 456 | 
            +
                  ".pub"       => "application/x-mspublisher",
         | 
| 457 | 
            +
                  ".pvb"       => "application/vnd.3gpp.pic-bw-var",
         | 
| 458 | 
            +
                  ".pwn"       => "application/vnd.3m.post-it-notes",
         | 
| 459 | 
            +
                  ".py"        => "text/x-script.python",
         | 
| 460 | 
            +
                  ".pya"       => "audio/vnd.ms-playready.media.pya",
         | 
| 461 | 
            +
                  ".pyv"       => "video/vnd.ms-playready.media.pyv",
         | 
| 462 | 
            +
                  ".qam"       => "application/vnd.epson.quickanime",
         | 
| 463 | 
            +
                  ".qbo"       => "application/vnd.intu.qbo",
         | 
| 464 | 
            +
                  ".qfx"       => "application/vnd.intu.qfx",
         | 
| 465 | 
            +
                  ".qps"       => "application/vnd.publishare-delta-tree",
         | 
| 466 | 
            +
                  ".qt"        => "video/quicktime",
         | 
| 467 | 
            +
                  ".qtif"      => "image/x-quicktime",
         | 
| 468 | 
            +
                  ".qxd"       => "application/vnd.quark.quarkxpress",
         | 
| 469 | 
            +
                  ".ra"        => "audio/x-pn-realaudio",
         | 
| 470 | 
            +
                  ".rake"      => "text/x-script.ruby",
         | 
| 471 | 
            +
                  ".ram"       => "audio/x-pn-realaudio",
         | 
| 472 | 
            +
                  ".rar"       => "application/x-rar-compressed",
         | 
| 473 | 
            +
                  ".ras"       => "image/x-cmu-raster",
         | 
| 474 | 
            +
                  ".rb"        => "text/x-script.ruby",
         | 
| 475 | 
            +
                  ".rcprofile" => "application/vnd.ipunplugged.rcprofile",
         | 
| 476 | 
            +
                  ".rdf"       => "application/rdf+xml",
         | 
| 477 | 
            +
                  ".rdz"       => "application/vnd.data-vision.rdz",
         | 
| 478 | 
            +
                  ".rep"       => "application/vnd.businessobjects",
         | 
| 479 | 
            +
                  ".rgb"       => "image/x-rgb",
         | 
| 480 | 
            +
                  ".rif"       => "application/reginfo+xml",
         | 
| 481 | 
            +
                  ".rl"        => "application/resource-lists+xml",
         | 
| 482 | 
            +
                  ".rlc"       => "image/vnd.fujixerox.edmics-rlc",
         | 
| 483 | 
            +
                  ".rld"       => "application/resource-lists-diff+xml",
         | 
| 484 | 
            +
                  ".rm"        => "application/vnd.rn-realmedia",
         | 
| 485 | 
            +
                  ".rmp"       => "audio/x-pn-realaudio-plugin",
         | 
| 486 | 
            +
                  ".rms"       => "application/vnd.jcp.javame.midlet-rms",
         | 
| 487 | 
            +
                  ".rnc"       => "application/relax-ng-compact-syntax",
         | 
| 488 | 
            +
                  ".roff"      => "text/troff",
         | 
| 489 | 
            +
                  ".rpm"       => "application/x-redhat-package-manager",
         | 
| 490 | 
            +
                  ".rpss"      => "application/vnd.nokia.radio-presets",
         | 
| 491 | 
            +
                  ".rpst"      => "application/vnd.nokia.radio-preset",
         | 
| 492 | 
            +
                  ".rq"        => "application/sparql-query",
         | 
| 493 | 
            +
                  ".rs"        => "application/rls-services+xml",
         | 
| 494 | 
            +
                  ".rsd"       => "application/rsd+xml",
         | 
| 495 | 
            +
                  ".rss"       => "application/rss+xml",
         | 
| 496 | 
            +
                  ".rtf"       => "application/rtf",
         | 
| 497 | 
            +
                  ".rtx"       => "text/richtext",
         | 
| 498 | 
            +
                  ".ru"        => "text/x-script.ruby",
         | 
| 499 | 
            +
                  ".s"         => "text/x-asm",
         | 
| 500 | 
            +
                  ".saf"       => "application/vnd.yamaha.smaf-audio",
         | 
| 501 | 
            +
                  ".sbml"      => "application/sbml+xml",
         | 
| 502 | 
            +
                  ".sc"        => "application/vnd.ibm.secure-container",
         | 
| 503 | 
            +
                  ".scd"       => "application/x-msschedule",
         | 
| 504 | 
            +
                  ".scm"       => "application/vnd.lotus-screencam",
         | 
| 505 | 
            +
                  ".scq"       => "application/scvp-cv-request",
         | 
| 506 | 
            +
                  ".scs"       => "application/scvp-cv-response",
         | 
| 507 | 
            +
                  ".sdkm"      => "application/vnd.solent.sdkm+xml",
         | 
| 508 | 
            +
                  ".sdp"       => "application/sdp",
         | 
| 509 | 
            +
                  ".see"       => "application/vnd.seemail",
         | 
| 510 | 
            +
                  ".sema"      => "application/vnd.sema",
         | 
| 511 | 
            +
                  ".semd"      => "application/vnd.semd",
         | 
| 512 | 
            +
                  ".semf"      => "application/vnd.semf",
         | 
| 513 | 
            +
                  ".setpay"    => "application/set-payment-initiation",
         | 
| 514 | 
            +
                  ".setreg"    => "application/set-registration-initiation",
         | 
| 515 | 
            +
                  ".sfd"       => "application/vnd.hydrostatix.sof-data",
         | 
| 516 | 
            +
                  ".sfs"       => "application/vnd.spotfire.sfs",
         | 
| 517 | 
            +
                  ".sgm"       => "text/sgml",
         | 
| 518 | 
            +
                  ".sgml"      => "text/sgml",
         | 
| 519 | 
            +
                  ".sh"        => "application/x-sh",
         | 
| 520 | 
            +
                  ".shar"      => "application/x-shar",
         | 
| 521 | 
            +
                  ".shf"       => "application/shf+xml",
         | 
| 522 | 
            +
                  ".sig"       => "application/pgp-signature",
         | 
| 523 | 
            +
                  ".sit"       => "application/x-stuffit",
         | 
| 524 | 
            +
                  ".sitx"      => "application/x-stuffitx",
         | 
| 525 | 
            +
                  ".skp"       => "application/vnd.koan",
         | 
| 526 | 
            +
                  ".slt"       => "application/vnd.epson.salt",
         | 
| 527 | 
            +
                  ".smi"       => "application/smil+xml",
         | 
| 528 | 
            +
                  ".snd"       => "audio/basic",
         | 
| 529 | 
            +
                  ".so"        => "application/octet-stream",
         | 
| 530 | 
            +
                  ".spf"       => "application/vnd.yamaha.smaf-phrase",
         | 
| 531 | 
            +
                  ".spl"       => "application/x-futuresplash",
         | 
| 532 | 
            +
                  ".spot"      => "text/vnd.in3d.spot",
         | 
| 533 | 
            +
                  ".spp"       => "application/scvp-vp-response",
         | 
| 534 | 
            +
                  ".spq"       => "application/scvp-vp-request",
         | 
| 535 | 
            +
                  ".src"       => "application/x-wais-source",
         | 
| 536 | 
            +
                  ".srx"       => "application/sparql-results+xml",
         | 
| 537 | 
            +
                  ".sse"       => "application/vnd.kodak-descriptor",
         | 
| 538 | 
            +
                  ".ssf"       => "application/vnd.epson.ssf",
         | 
| 539 | 
            +
                  ".ssml"      => "application/ssml+xml",
         | 
| 540 | 
            +
                  ".stf"       => "application/vnd.wt.stf",
         | 
| 541 | 
            +
                  ".stk"       => "application/hyperstudio",
         | 
| 542 | 
            +
                  ".str"       => "application/vnd.pg.format",
         | 
| 543 | 
            +
                  ".sus"       => "application/vnd.sus-calendar",
         | 
| 544 | 
            +
                  ".sv4cpio"   => "application/x-sv4cpio",
         | 
| 545 | 
            +
                  ".sv4crc"    => "application/x-sv4crc",
         | 
| 546 | 
            +
                  ".svd"       => "application/vnd.svd",
         | 
| 547 | 
            +
                  ".svg"       => "image/svg+xml",
         | 
| 548 | 
            +
                  ".svgz"      => "image/svg+xml",
         | 
| 549 | 
            +
                  ".swf"       => "application/x-shockwave-flash",
         | 
| 550 | 
            +
                  ".swi"       => "application/vnd.arastra.swi",
         | 
| 551 | 
            +
                  ".t"         => "text/troff",
         | 
| 552 | 
            +
                  ".tao"       => "application/vnd.tao.intent-module-archive",
         | 
| 553 | 
            +
                  ".tar"       => "application/x-tar",
         | 
| 554 | 
            +
                  ".tbz"       => "application/x-bzip-compressed-tar",
         | 
| 555 | 
            +
                  ".tcap"      => "application/vnd.3gpp2.tcap",
         | 
| 556 | 
            +
                  ".tcl"       => "application/x-tcl",
         | 
| 557 | 
            +
                  ".tex"       => "application/x-tex",
         | 
| 558 | 
            +
                  ".texi"      => "application/x-texinfo",
         | 
| 559 | 
            +
                  ".texinfo"   => "application/x-texinfo",
         | 
| 560 | 
            +
                  ".text"      => "text/plain",
         | 
| 561 | 
            +
                  ".tif"       => "image/tiff",
         | 
| 562 | 
            +
                  ".tiff"      => "image/tiff",
         | 
| 563 | 
            +
                  ".tmo"       => "application/vnd.tmobile-livetv",
         | 
| 564 | 
            +
                  ".torrent"   => "application/x-bittorrent",
         | 
| 565 | 
            +
                  ".tpl"       => "application/vnd.groove-tool-template",
         | 
| 566 | 
            +
                  ".tpt"       => "application/vnd.trid.tpt",
         | 
| 567 | 
            +
                  ".tr"        => "text/troff",
         | 
| 568 | 
            +
                  ".tra"       => "application/vnd.trueapp",
         | 
| 569 | 
            +
                  ".trm"       => "application/x-msterminal",
         | 
| 570 | 
            +
                  ".tsv"       => "text/tab-separated-values",
         | 
| 571 | 
            +
                  ".ttf"       => "application/octet-stream",
         | 
| 572 | 
            +
                  ".twd"       => "application/vnd.simtech-mindmapper",
         | 
| 573 | 
            +
                  ".txd"       => "application/vnd.genomatix.tuxedo",
         | 
| 574 | 
            +
                  ".txf"       => "application/vnd.mobius.txf",
         | 
| 575 | 
            +
                  ".txt"       => "text/plain",
         | 
| 576 | 
            +
                  ".ufd"       => "application/vnd.ufdl",
         | 
| 577 | 
            +
                  ".umj"       => "application/vnd.umajin",
         | 
| 578 | 
            +
                  ".unityweb"  => "application/vnd.unity",
         | 
| 579 | 
            +
                  ".uoml"      => "application/vnd.uoml+xml",
         | 
| 580 | 
            +
                  ".uri"       => "text/uri-list",
         | 
| 581 | 
            +
                  ".ustar"     => "application/x-ustar",
         | 
| 582 | 
            +
                  ".utz"       => "application/vnd.uiq.theme",
         | 
| 583 | 
            +
                  ".uu"        => "text/x-uuencode",
         | 
| 584 | 
            +
                  ".vcd"       => "application/x-cdlink",
         | 
| 585 | 
            +
                  ".vcf"       => "text/x-vcard",
         | 
| 586 | 
            +
                  ".vcg"       => "application/vnd.groove-vcard",
         | 
| 587 | 
            +
                  ".vcs"       => "text/x-vcalendar",
         | 
| 588 | 
            +
                  ".vcx"       => "application/vnd.vcx",
         | 
| 589 | 
            +
                  ".vis"       => "application/vnd.visionary",
         | 
| 590 | 
            +
                  ".viv"       => "video/vnd.vivo",
         | 
| 591 | 
            +
                  ".vrml"      => "model/vrml",
         | 
| 592 | 
            +
                  ".vsd"       => "application/vnd.visio",
         | 
| 593 | 
            +
                  ".vsf"       => "application/vnd.vsf",
         | 
| 594 | 
            +
                  ".vtu"       => "model/vnd.vtu",
         | 
| 595 | 
            +
                  ".vxml"      => "application/voicexml+xml",
         | 
| 596 | 
            +
                  ".war"       => "application/java-archive",
         | 
| 597 | 
            +
                  ".wav"       => "audio/x-wav",
         | 
| 598 | 
            +
                  ".wax"       => "audio/x-ms-wax",
         | 
| 599 | 
            +
                  ".wbmp"      => "image/vnd.wap.wbmp",
         | 
| 600 | 
            +
                  ".wbs"       => "application/vnd.criticaltools.wbs+xml",
         | 
| 601 | 
            +
                  ".wbxml"     => "application/vnd.wap.wbxml",
         | 
| 602 | 
            +
                  ".webm"      => "video/webm",
         | 
| 603 | 
            +
                  ".wm"        => "video/x-ms-wm",
         | 
| 604 | 
            +
                  ".wma"       => "audio/x-ms-wma",
         | 
| 605 | 
            +
                  ".wmd"       => "application/x-ms-wmd",
         | 
| 606 | 
            +
                  ".wmf"       => "application/x-msmetafile",
         | 
| 607 | 
            +
                  ".wml"       => "text/vnd.wap.wml",
         | 
| 608 | 
            +
                  ".wmlc"      => "application/vnd.wap.wmlc",
         | 
| 609 | 
            +
                  ".wmls"      => "text/vnd.wap.wmlscript",
         | 
| 610 | 
            +
                  ".wmlsc"     => "application/vnd.wap.wmlscriptc",
         | 
| 611 | 
            +
                  ".wmv"       => "video/x-ms-wmv",
         | 
| 612 | 
            +
                  ".wmx"       => "video/x-ms-wmx",
         | 
| 613 | 
            +
                  ".wmz"       => "application/x-ms-wmz",
         | 
| 614 | 
            +
                  ".woff"      => "application/font-woff",
         | 
| 615 | 
            +
                  ".wpd"       => "application/vnd.wordperfect",
         | 
| 616 | 
            +
                  ".wpl"       => "application/vnd.ms-wpl",
         | 
| 617 | 
            +
                  ".wps"       => "application/vnd.ms-works",
         | 
| 618 | 
            +
                  ".wqd"       => "application/vnd.wqd",
         | 
| 619 | 
            +
                  ".wri"       => "application/x-mswrite",
         | 
| 620 | 
            +
                  ".wrl"       => "model/vrml",
         | 
| 621 | 
            +
                  ".wsdl"      => "application/wsdl+xml",
         | 
| 622 | 
            +
                  ".wspolicy"  => "application/wspolicy+xml",
         | 
| 623 | 
            +
                  ".wtb"       => "application/vnd.webturbo",
         | 
| 624 | 
            +
                  ".wvx"       => "video/x-ms-wvx",
         | 
| 625 | 
            +
                  ".x3d"       => "application/vnd.hzn-3d-crossword",
         | 
| 626 | 
            +
                  ".xar"       => "application/vnd.xara",
         | 
| 627 | 
            +
                  ".xbd"       => "application/vnd.fujixerox.docuworks.binder",
         | 
| 628 | 
            +
                  ".xbm"       => "image/x-xbitmap",
         | 
| 629 | 
            +
                  ".xdm"       => "application/vnd.syncml.dm+xml",
         | 
| 630 | 
            +
                  ".xdp"       => "application/vnd.adobe.xdp+xml",
         | 
| 631 | 
            +
                  ".xdw"       => "application/vnd.fujixerox.docuworks",
         | 
| 632 | 
            +
                  ".xenc"      => "application/xenc+xml",
         | 
| 633 | 
            +
                  ".xer"       => "application/patch-ops-error+xml",
         | 
| 634 | 
            +
                  ".xfdf"      => "application/vnd.adobe.xfdf",
         | 
| 635 | 
            +
                  ".xfdl"      => "application/vnd.xfdl",
         | 
| 636 | 
            +
                  ".xhtml"     => "application/xhtml+xml",
         | 
| 637 | 
            +
                  ".xif"       => "image/vnd.xiff",
         | 
| 638 | 
            +
                  ".xls"       => "application/vnd.ms-excel",
         | 
| 639 | 
            +
                  ".xlsx"      => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
         | 
| 640 | 
            +
                  ".xml"       => "application/xml",
         | 
| 641 | 
            +
                  ".xo"        => "application/vnd.olpc-sugar",
         | 
| 642 | 
            +
                  ".xop"       => "application/xop+xml",
         | 
| 643 | 
            +
                  ".xpm"       => "image/x-xpixmap",
         | 
| 644 | 
            +
                  ".xpr"       => "application/vnd.is-xpr",
         | 
| 645 | 
            +
                  ".xps"       => "application/vnd.ms-xpsdocument",
         | 
| 646 | 
            +
                  ".xpw"       => "application/vnd.intercon.formnet",
         | 
| 647 | 
            +
                  ".xsl"       => "application/xml",
         | 
| 648 | 
            +
                  ".xslt"      => "application/xslt+xml",
         | 
| 649 | 
            +
                  ".xsm"       => "application/vnd.syncml+xml",
         | 
| 650 | 
            +
                  ".xspf"      => "application/xspf+xml",
         | 
| 651 | 
            +
                  ".xul"       => "application/vnd.mozilla.xul+xml",
         | 
| 652 | 
            +
                  ".xwd"       => "image/x-xwindowdump",
         | 
| 653 | 
            +
                  ".xyz"       => "chemical/x-xyz",
         | 
| 654 | 
            +
                  ".yaml"      => "text/yaml",
         | 
| 655 | 
            +
                  ".yml"       => "text/yaml",
         | 
| 656 | 
            +
                  ".zaz"       => "application/vnd.zzazz.deck+xml",
         | 
| 657 | 
            +
                  ".zip"       => "application/zip",
         | 
| 658 | 
            +
                  ".zmm"       => "application/vnd.handheld-entertainment+xml",
         | 
| 659 | 
            +
                }
         | 
| 660 | 
            +
              end
         | 
| 661 | 
            +
            end
         |