racknga 0.9.2 → 0.9.4
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/Gemfile +3 -12
- data/README.textile +9 -8
- data/Rakefile +19 -272
- data/doc/text/news.textile +20 -0
- data/lib/racknga/access_log_parser.rb +147 -0
- data/lib/racknga/api-keys.rb +40 -0
- data/lib/racknga/cache_database.rb +15 -5
- data/lib/racknga/exception_mail_notifier.rb +6 -6
- data/lib/racknga/log_database.rb +2 -1
- data/lib/racknga/log_entry.rb +85 -0
- data/lib/racknga/middleware/auth/api-key.rb +95 -0
- data/lib/racknga/middleware/cache.rb +22 -8
- data/lib/racknga/middleware/deflater.rb +13 -3
- data/lib/racknga/middleware/exception_notifier.rb +1 -2
- data/lib/racknga/middleware/instance_name.rb +92 -9
- data/lib/racknga/middleware/jsonp.rb +25 -5
- data/lib/racknga/middleware/log.rb +8 -3
- data/lib/racknga/middleware/nginx_raw_uri.rb +65 -0
- data/lib/racknga/middleware/range.rb +1 -1
- data/lib/racknga/reverse_line_reader.rb +1 -1
- data/lib/racknga/utils.rb +1 -1
- data/lib/racknga/version.rb +2 -2
- data/lib/racknga.rb +4 -2
- data/munin/plugins/passenger_application_ +61 -47
- data/munin/plugins/passenger_status +64 -33
- data/test/racknga-test-utils.rb +2 -1
- data/test/run-test.rb +1 -3
- data/test/{test-nginx-log-parser.rb → test-access-log-parser.rb} +115 -26
- data/test/test-api-keys.rb +80 -0
- data/test/test-middleware-auth-api-key.rb +144 -0
- data/test/test-middleware-cache.rb +1 -1
- data/test/test-middleware-instance-name.rb +50 -16
- data/test/test-middleware-jsonp.rb +14 -2
- data/test/test-middleware-nginx-raw-uri.rb +70 -0
- data/test/test-middleware-range.rb +1 -1
- metadata +159 -155
- data/lib/racknga/nginx_access_log_parser.rb +0 -139
- data/lib/racknga/will_paginate.rb +0 -48
| @@ -15,34 +15,37 @@ | |
| 15 15 | 
             
            #
         | 
| 16 16 | 
             
            # You should have received a copy of the GNU Lesser General Public
         | 
| 17 17 | 
             
            # License along with this library; if not, write to the Free Software
         | 
| 18 | 
            -
            # Foundation, Inc.,  | 
| 18 | 
            +
            # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
         | 
| 19 19 |  | 
| 20 20 | 
             
            require 'stringio'
         | 
| 21 21 |  | 
| 22 | 
            -
            module  | 
| 22 | 
            +
            module AccessLogParserTests
         | 
| 23 23 | 
             
              module Data
         | 
| 24 24 | 
             
                private
         | 
| 25 | 
            -
                def  | 
| 26 | 
            -
                   | 
| 27 | 
            -
             | 
| 25 | 
            +
                def time_local
         | 
| 26 | 
            +
                  "03/Aug/2011:16:58:01 +0900"
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def log_line(content)
         | 
| 30 | 
            +
                  content
         | 
| 28 31 | 
             
                end
         | 
| 29 32 |  | 
| 30 33 | 
             
                def usual_log_line
         | 
| 31 | 
            -
                  "127.0.0.1 - - #{time_log_component}  " +
         | 
| 32 | 
            -
             | 
| 34 | 
            +
                  log_line("127.0.0.1 - - #{time_log_component}  " +
         | 
| 35 | 
            +
                           "\"GET / HTTP/1.1\" 200 613 \"-\" \"Ruby\"")
         | 
| 33 36 | 
             
                end
         | 
| 34 37 |  | 
| 35 38 | 
             
                def usual_log_entry_options
         | 
| 36 39 | 
             
                  {
         | 
| 37 40 | 
             
                    :remote_address => "127.0.0.1",
         | 
| 38 | 
            -
                    :remote_user =>  | 
| 41 | 
            +
                    :remote_user => nil,
         | 
| 39 42 | 
             
                    :time_local => Time.local(2011, 8, 3, 16, 58, 1),
         | 
| 40 43 | 
             
                    :runtime => runtime,
         | 
| 41 44 | 
             
                    :request_time => request_time,
         | 
| 42 45 | 
             
                    :request => "GET / HTTP/1.1",
         | 
| 43 46 | 
             
                    :status => 200,
         | 
| 44 47 | 
             
                    :body_bytes_sent => 613,
         | 
| 45 | 
            -
                    :http_referer =>  | 
| 48 | 
            +
                    :http_referer => nil,
         | 
| 46 49 | 
             
                    :http_user_agent => "Ruby",
         | 
| 47 50 | 
             
                  }
         | 
| 48 51 | 
             
                end
         | 
| @@ -52,8 +55,8 @@ module NginxAccessLogParserTests | |
| 52 55 | 
             
                end
         | 
| 53 56 |  | 
| 54 57 | 
             
                def not_found_log_line
         | 
| 55 | 
            -
                  "127.0.0.1 - - #{time_log_component}  " +
         | 
| 56 | 
            -
             | 
| 58 | 
            +
                  log_line("127.0.0.1 - - #{time_log_component}  " +
         | 
| 59 | 
            +
                           "\"GET /the-truth.html HTTP/1.1\" 404 613 \"-\" \"Ruby\"")
         | 
| 57 60 | 
             
                end
         | 
| 58 61 |  | 
| 59 62 | 
             
                def not_found_log_entry
         | 
| @@ -71,8 +74,8 @@ module NginxAccessLogParserTests | |
| 71 74 | 
             
                def valid_utf8_log_line
         | 
| 72 75 | 
             
                  path = utf8_path
         | 
| 73 76 |  | 
| 74 | 
            -
                  "127.0.0.1 - - #{time_log_component}  " +
         | 
| 75 | 
            -
             | 
| 77 | 
            +
                  log_line("127.0.0.1 - - #{time_log_component}  " +
         | 
| 78 | 
            +
                           "\"GET #{path} HTTP/1.1\" 200 613 \"-\" \"Ruby\"")
         | 
| 76 79 | 
             
                end
         | 
| 77 80 |  | 
| 78 81 | 
             
                def valid_utf8_log_entry
         | 
| @@ -90,8 +93,41 @@ module NginxAccessLogParserTests | |
| 90 93 | 
             
                def invalid_utf8_log_line
         | 
| 91 94 | 
             
                  path = garbled_path
         | 
| 92 95 |  | 
| 93 | 
            -
                  "127.0.0.1 - - #{time_log_component}  " +
         | 
| 94 | 
            -
             | 
| 96 | 
            +
                  log_line("127.0.0.1 - - #{time_log_component}  " +
         | 
| 97 | 
            +
                           "\"GET #{path} HTTP/1.1\" 200 613 \"-\" \"Ruby\"")
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                def ipv6_log_line
         | 
| 101 | 
            +
                  log_line("::1 - - #{time_log_component}  " +
         | 
| 102 | 
            +
                           "\"GET / HTTP/1.1\" 200 613 \"-\" \"Ruby\"")
         | 
| 103 | 
            +
                end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                def ipv6_log_entry
         | 
| 106 | 
            +
                  options = {
         | 
| 107 | 
            +
                    :remote_address => "::1",
         | 
| 108 | 
            +
                  }
         | 
| 109 | 
            +
                  create_log_entry(usual_log_entry_options.merge(options))
         | 
| 110 | 
            +
                end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                def apache_combined_log_line
         | 
| 113 | 
            +
                  log_line("127.0.0.1 - - #{time_log_component} " +
         | 
| 114 | 
            +
                           "\"GET / HTTP/1.1\" 200 613 \"-\" \"Ruby\"")
         | 
| 115 | 
            +
                end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                def apache_combined_log_entry
         | 
| 118 | 
            +
                  usual_log_entry
         | 
| 119 | 
            +
                end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                def no_body_bytes_sent_log_line
         | 
| 122 | 
            +
                  log_line("127.0.0.1 - - #{time_log_component}  " +
         | 
| 123 | 
            +
                           "\"GET / HTTP/1.1\" 200 - \"-\" \"Ruby\"")
         | 
| 124 | 
            +
                end
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                def no_body_bytes_sent_log_entry
         | 
| 127 | 
            +
                  options = {
         | 
| 128 | 
            +
                    :body_bytes_sent => nil,
         | 
| 129 | 
            +
                  }
         | 
| 130 | 
            +
                  create_log_entry(usual_log_entry_options.merge(options))
         | 
| 95 131 | 
             
                end
         | 
| 96 132 |  | 
| 97 133 | 
             
                def bad_log_line
         | 
| @@ -110,11 +146,11 @@ module NginxAccessLogParserTests | |
| 110 146 | 
             
                end
         | 
| 111 147 |  | 
| 112 148 | 
             
                def create_log_parser(file)
         | 
| 113 | 
            -
                  Racknga:: | 
| 149 | 
            +
                  Racknga::AccessLogParser.new(file)
         | 
| 114 150 | 
             
                end
         | 
| 115 151 |  | 
| 116 152 | 
             
                def create_reversed_log_parser(file)
         | 
| 117 | 
            -
                  Racknga:: | 
| 153 | 
            +
                  Racknga::ReversedAccessLogParser.new(file)
         | 
| 118 154 | 
             
                end
         | 
| 119 155 |  | 
| 120 156 | 
             
                def join_lines(*lines)
         | 
| @@ -137,18 +173,36 @@ module NginxAccessLogParserTests | |
| 137 173 | 
             
              end
         | 
| 138 174 |  | 
| 139 175 | 
             
              module Tests
         | 
| 140 | 
            -
                def  | 
| 176 | 
            +
                def test_usual_log
         | 
| 141 177 | 
             
                  accesses = parse(join_lines(usual_log_line))
         | 
| 142 | 
            -
                   | 
| 143 | 
            -
             | 
| 178 | 
            +
                  assert_equal([usual_log_entry],
         | 
| 179 | 
            +
                               accesses)
         | 
| 144 180 | 
             
                end
         | 
| 145 181 |  | 
| 146 | 
            -
                def  | 
| 182 | 
            +
                def test_ipv6_log
         | 
| 183 | 
            +
                  accesses = parse(join_lines(ipv6_log_line))
         | 
| 184 | 
            +
                  assert_equal([ipv6_log_entry],
         | 
| 185 | 
            +
                               accesses)
         | 
| 186 | 
            +
                end
         | 
| 187 | 
            +
             | 
| 188 | 
            +
                def test_apache_combined_log
         | 
| 189 | 
            +
                  accesses = parse(join_lines(apache_combined_log_line))
         | 
| 190 | 
            +
                  assert_equal([apache_combined_log_entry],
         | 
| 191 | 
            +
                               accesses)
         | 
| 192 | 
            +
                end
         | 
| 193 | 
            +
             | 
| 194 | 
            +
                def test_no_body_bytes_sent_log
         | 
| 195 | 
            +
                  accesses = parse(join_lines(no_body_bytes_sent_log_line))
         | 
| 196 | 
            +
                  assert_equal([no_body_bytes_sent_log_entry],
         | 
| 197 | 
            +
                               accesses)
         | 
| 198 | 
            +
                end
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                def test_no_log
         | 
| 147 201 | 
             
                  accesses = parse(join_lines())
         | 
| 148 202 | 
             
                  assert_equal([], accesses)
         | 
| 149 203 | 
             
                end
         | 
| 150 204 |  | 
| 151 | 
            -
                def  | 
| 205 | 
            +
                def test_multiple_logs
         | 
| 152 206 | 
             
                  accesses = parse(join_lines(usual_log_line,
         | 
| 153 207 | 
             
                                              usual_log_line,
         | 
| 154 208 | 
             
                                              not_found_log_line))
         | 
| @@ -158,7 +212,7 @@ module NginxAccessLogParserTests | |
| 158 212 | 
             
                               accesses)
         | 
| 159 213 | 
             
                end
         | 
| 160 214 |  | 
| 161 | 
            -
                def  | 
| 215 | 
            +
                def test_reversed_parse
         | 
| 162 216 | 
             
                  accesses = reversed_parse(join_lines(usual_log_line,
         | 
| 163 217 | 
             
                                                       usual_log_line,
         | 
| 164 218 | 
             
                                                       not_found_log_line))
         | 
| @@ -168,8 +222,8 @@ module NginxAccessLogParserTests | |
| 168 222 | 
             
                               accesses)
         | 
| 169 223 | 
             
                end
         | 
| 170 224 |  | 
| 171 | 
            -
                def  | 
| 172 | 
            -
                  assert_raise(Racknga:: | 
| 225 | 
            +
                def test_bad_log
         | 
| 226 | 
            +
                  assert_raise(Racknga::AccessLogParser::FormatError) do
         | 
| 173 227 | 
             
                    parse(join_lines(bad_log_line))
         | 
| 174 228 | 
             
                  end
         | 
| 175 229 | 
             
                end
         | 
| @@ -189,6 +243,12 @@ module NginxAccessLogParserTests | |
| 189 243 | 
             
                include Data
         | 
| 190 244 | 
             
                include Tests
         | 
| 191 245 |  | 
| 246 | 
            +
                private
         | 
| 247 | 
            +
                def time_log_component
         | 
| 248 | 
            +
                  times = [time_local, runtime, request_time].compact
         | 
| 249 | 
            +
                  "[#{times.join(', ')}]"
         | 
| 250 | 
            +
                end
         | 
| 251 | 
            +
             | 
| 192 252 | 
             
                def runtime
         | 
| 193 253 | 
             
                  nil
         | 
| 194 254 | 
             
                end
         | 
| @@ -198,11 +258,40 @@ module NginxAccessLogParserTests | |
| 198 258 | 
             
                end
         | 
| 199 259 | 
             
              end
         | 
| 200 260 |  | 
| 201 | 
            -
              class  | 
| 261 | 
            +
              class CombinedWithTimeNginxLogTest < Test::Unit::TestCase
         | 
| 262 | 
            +
                include Environment
         | 
| 263 | 
            +
                include Data
         | 
| 264 | 
            +
                include Tests
         | 
| 265 | 
            +
             | 
| 266 | 
            +
                private
         | 
| 267 | 
            +
                def time_log_component
         | 
| 268 | 
            +
                  times = [time_local, runtime, request_time].compact
         | 
| 269 | 
            +
                  "[#{times.join(', ')}]"
         | 
| 270 | 
            +
                end
         | 
| 271 | 
            +
             | 
| 272 | 
            +
                def runtime
         | 
| 273 | 
            +
                  0.000573
         | 
| 274 | 
            +
                end
         | 
| 275 | 
            +
             | 
| 276 | 
            +
                def request_time
         | 
| 277 | 
            +
                  0.001
         | 
| 278 | 
            +
                end
         | 
| 279 | 
            +
              end
         | 
| 280 | 
            +
             | 
| 281 | 
            +
              class CombinedWithTimeApacheLogTest < Test::Unit::TestCase
         | 
| 202 282 | 
             
                include Environment
         | 
| 203 283 | 
             
                include Data
         | 
| 204 284 | 
             
                include Tests
         | 
| 205 285 |  | 
| 286 | 
            +
                private
         | 
| 287 | 
            +
                def time_log_component
         | 
| 288 | 
            +
                  "[#{time_local}]"
         | 
| 289 | 
            +
                end
         | 
| 290 | 
            +
             | 
| 291 | 
            +
                def log_line(content)
         | 
| 292 | 
            +
                  "#{content} #{runtime} #{(request_time * 1_000_000).to_i}"
         | 
| 293 | 
            +
                end
         | 
| 294 | 
            +
             | 
| 206 295 | 
             
                def runtime
         | 
| 207 296 | 
             
                  0.000573
         | 
| 208 297 | 
             
                end
         | 
| @@ -0,0 +1,80 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # Copyright (C) 2012  Haruka Yoshihara <yoshihara@clear-code.com>
         | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
            # This library is free software; you can redistribute it and/or
         | 
| 6 | 
            +
            # modify it under the terms of the GNU Lesser General Public
         | 
| 7 | 
            +
            # License as published by the Free Software Foundation; either
         | 
| 8 | 
            +
            # version 2.1 of the License, or (at your option) any later version.
         | 
| 9 | 
            +
            #
         | 
| 10 | 
            +
            # This library is distributed in the hope that it will be useful,
         | 
| 11 | 
            +
            # but WITHOUT ANY WARRANTY; without even the implied warranty of
         | 
| 12 | 
            +
            # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
         | 
| 13 | 
            +
            # Lesser General Public License for more details.
         | 
| 14 | 
            +
            #
         | 
| 15 | 
            +
            # You should have received a copy of the GNU Lesser General Public
         | 
| 16 | 
            +
            # License along with this library; if not, write to the Free Software
         | 
| 17 | 
            +
            # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            class APIKeysTest < Test::Unit::TestCase
         | 
| 20 | 
            +
              include RackngaTestUtils
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              def setup
         | 
| 23 | 
            +
                @api_keys = Racknga::APIKeys.new(query_parameter, api_keys)
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              def test_matched_key
         | 
| 27 | 
            +
                assert_matched(query_parameter, api_key)
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              def test_not_matched_key
         | 
| 31 | 
            +
                assert_not_matched(query_parameter, "notapikey")
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              def test_empty_key
         | 
| 35 | 
            +
                assert_not_matched(query_parameter, "")
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              def test_empty_query_parameter
         | 
| 39 | 
            +
                assert_not_matched("", api_key)
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              def test_mismatched_query_parameter
         | 
| 43 | 
            +
                assert_not_matched("not-api-key", api_key)
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
              private
         | 
| 47 | 
            +
              def assert_matched(parameter, key)
         | 
| 48 | 
            +
                environment = generate_environment(parameter, key)
         | 
| 49 | 
            +
                assert_true(@api_keys.include?(environment))
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              def assert_not_matched(parameter, key)
         | 
| 53 | 
            +
                environment = generate_environment(parameter, key)
         | 
| 54 | 
            +
                assert_false(@api_keys.include?(environment))
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              def generate_environment(parameter, key)
         | 
| 58 | 
            +
                url = "http://example.org"
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                unless parameter.empty?
         | 
| 61 | 
            +
                  api_url = "#{url}?#{parameter}=#{key}"
         | 
| 62 | 
            +
                else
         | 
| 63 | 
            +
                  api_url = url
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                Rack::MockRequest.env_for(api_url)
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
              def query_parameter
         | 
| 70 | 
            +
                "api-key"
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              def api_keys
         | 
| 74 | 
            +
                ["key", "key2"]
         | 
| 75 | 
            +
              end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
              def api_key
         | 
| 78 | 
            +
                api_keys.first
         | 
| 79 | 
            +
              end
         | 
| 80 | 
            +
            end
         | 
| @@ -0,0 +1,144 @@ | |
| 1 | 
            +
            # Copyright (C) 2012  Haruka Yoshihara <kou@clear-code.com>
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # This library is free software; you can redistribute it and/or
         | 
| 4 | 
            +
            # modify it under the terms of the GNU Lesser General Public
         | 
| 5 | 
            +
            # License as published by the Free Software Foundation; either
         | 
| 6 | 
            +
            # version 2.1 of the License, or (at your option) any later version.
         | 
| 7 | 
            +
            #
         | 
| 8 | 
            +
            # This library is distributed in the hope that it will be useful,
         | 
| 9 | 
            +
            # but WITHOUT ANY WARRANTY; without even the implied warranty of
         | 
| 10 | 
            +
            # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
         | 
| 11 | 
            +
            # Lesser General Public License for more details.
         | 
| 12 | 
            +
            #
         | 
| 13 | 
            +
            # You should have received a copy of the GNU Lesser General Public
         | 
| 14 | 
            +
            # License along with this library; if not, write to the Free Software
         | 
| 15 | 
            +
            # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            class MiddlewareAuthAPIKeyTest < Test::Unit::TestCase
         | 
| 18 | 
            +
              include RackngaTestUtils
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              def app
         | 
| 21 | 
            +
                application = Proc.new do |environment|
         | 
| 22 | 
            +
                  @environment = environment
         | 
| 23 | 
            +
                  [
         | 
| 24 | 
            +
                    200,
         | 
| 25 | 
            +
                    {"Content-Type" => "application/json"},
         | 
| 26 | 
            +
                    [@body]
         | 
| 27 | 
            +
                  ]
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
                authorized_api_keys =
         | 
| 30 | 
            +
                  Racknga::APIKeys.new(@api_query_parameter, @api_keys)
         | 
| 31 | 
            +
                api_key_options = {
         | 
| 32 | 
            +
                  :api_url_prefixes => [@api_url_prefix],
         | 
| 33 | 
            +
                  :authorized_api_keys => authorized_api_keys,
         | 
| 34 | 
            +
                  :error_response => @error_response,
         | 
| 35 | 
            +
                  :disable_authorization => disable_authorization?
         | 
| 36 | 
            +
                }
         | 
| 37 | 
            +
                api_key = api_key_authorizer(application, api_key_options)
         | 
| 38 | 
            +
                Proc.new do |environment|
         | 
| 39 | 
            +
                  api_key.call(environment)
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              def setup
         | 
| 44 | 
            +
                @api_query_parameter = "api-key"
         | 
| 45 | 
            +
                @api_url_prefix = "/api"
         | 
| 46 | 
            +
                @api_keys = ["key1", "key2"]
         | 
| 47 | 
            +
                @body = "{}"
         | 
| 48 | 
            +
                @error_response = {"error" => "this api key is not authorized"}
         | 
| 49 | 
            +
                Capybara.app = app
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              def test_authorized_key
         | 
| 53 | 
            +
                url = generate_url(url_prefix, query_parameter, valid_key)
         | 
| 54 | 
            +
                visit(url)
         | 
| 55 | 
            +
                assert_success_response
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              def test_unauthorized_key
         | 
| 59 | 
            +
                url = generate_url(url_prefix, query_parameter, "invalidkey")
         | 
| 60 | 
            +
                visit(url)
         | 
| 61 | 
            +
                assert_failure_response
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
              def test_unmatched_query_parameter
         | 
| 65 | 
            +
                url = generate_url(url_prefix, "not-api-key", valid_key)
         | 
| 66 | 
            +
                visit(url)
         | 
| 67 | 
            +
                assert_failure_response
         | 
| 68 | 
            +
              end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
              def test_unauthorized_key_and_unmatched_query_parameter
         | 
| 71 | 
            +
                url = generate_url(url_prefix, "not-api-key", "invalidkey")
         | 
| 72 | 
            +
                visit(url)
         | 
| 73 | 
            +
                assert_failure_response
         | 
| 74 | 
            +
              end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
              def test_not_api_url
         | 
| 77 | 
            +
                visit("/not/api/url")
         | 
| 78 | 
            +
                assert_success_response
         | 
| 79 | 
            +
              end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
              private
         | 
| 82 | 
            +
              def disable_authorization?
         | 
| 83 | 
            +
                false
         | 
| 84 | 
            +
              end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
              def api_key_authorizer(application, api_key_options)
         | 
| 87 | 
            +
                Racknga::Middleware::Auth::APIKey.new(application, api_key_options)
         | 
| 88 | 
            +
              end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
              def generate_url(path, query_parameter, api_key)
         | 
| 91 | 
            +
                url = path
         | 
| 92 | 
            +
                if query_parameter
         | 
| 93 | 
            +
                  url << "?#{query_parameter}=#{api_key}"
         | 
| 94 | 
            +
                end
         | 
| 95 | 
            +
                url
         | 
| 96 | 
            +
              end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
              def url_prefix
         | 
| 99 | 
            +
                @api_url_prefix
         | 
| 100 | 
            +
              end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
              def query_parameter
         | 
| 103 | 
            +
                @api_query_parameter
         | 
| 104 | 
            +
              end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
              def valid_key
         | 
| 107 | 
            +
                @api_keys.first
         | 
| 108 | 
            +
              end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
              def assert_success_response
         | 
| 111 | 
            +
                assert_equal(200, page.status_code)
         | 
| 112 | 
            +
                assert_equal(@body, page.source)
         | 
| 113 | 
            +
              end
         | 
| 114 | 
            +
             | 
| 115 | 
            +
              def assert_failure_response
         | 
| 116 | 
            +
                assert_equal(401, page.status_code)
         | 
| 117 | 
            +
                assert_equal(@error_response.to_json, page.source)
         | 
| 118 | 
            +
              end
         | 
| 119 | 
            +
             | 
| 120 | 
            +
              class DisableAuthorizationTest < self
         | 
| 121 | 
            +
                def test_unauthorized_key
         | 
| 122 | 
            +
                  url = generate_url(url_prefix, query_parameter, "invalidkey")
         | 
| 123 | 
            +
                  visit(url)
         | 
| 124 | 
            +
                  assert_success_response
         | 
| 125 | 
            +
                end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                def test_unmatched_query_parameter
         | 
| 128 | 
            +
                  url = generate_url(url_prefix, "not-api-key", valid_key)
         | 
| 129 | 
            +
                  visit(url)
         | 
| 130 | 
            +
                  assert_success_response
         | 
| 131 | 
            +
                end
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                def test_unauthorized_key_and_unmatched_query_parameter
         | 
| 134 | 
            +
                  url = generate_url(url_prefix, "not-api-key", "invalidkey")
         | 
| 135 | 
            +
                  visit(url)
         | 
| 136 | 
            +
                  assert_success_response
         | 
| 137 | 
            +
                end
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                private
         | 
| 140 | 
            +
                def disable_authorization?
         | 
| 141 | 
            +
                  true
         | 
| 142 | 
            +
                end
         | 
| 143 | 
            +
              end
         | 
| 144 | 
            +
            end
         | 
| @@ -12,7 +12,7 @@ | |
| 12 12 | 
             
            #
         | 
| 13 13 | 
             
            # You should have received a copy of the GNU Lesser General Public
         | 
| 14 14 | 
             
            # License along with this library; if not, write to the Free Software
         | 
| 15 | 
            -
            # Foundation, Inc.,  | 
| 15 | 
            +
            # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
         | 
| 16 16 |  | 
| 17 17 | 
             
            class MiddlewareCacheTest < Test::Unit::TestCase
         | 
| 18 18 | 
             
              include RackngaTestUtils
         | 
| @@ -12,45 +12,57 @@ | |
| 12 12 | 
             
            #
         | 
| 13 13 | 
             
            # You should have received a copy of the GNU Lesser General Public
         | 
| 14 14 | 
             
            # License along with this library; if not, write to the Free Software
         | 
| 15 | 
            -
            # Foundation, Inc.,  | 
| 15 | 
            +
            # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
         | 
| 16 16 |  | 
| 17 17 | 
             
            class InstanceNameTest < Test::Unit::TestCase
         | 
| 18 18 | 
             
              include RackngaTestUtils
         | 
| 19 19 |  | 
| 20 | 
            +
              DEFAULT_HEADER_NAME = "X-Responsed-By"
         | 
| 21 | 
            +
             | 
| 20 22 | 
             
              def test_no_option
         | 
| 21 | 
            -
                 | 
| 22 | 
            -
                user = default_instance_name.user
         | 
| 23 | 
            -
                revision = default_instance_name.revision
         | 
| 23 | 
            +
                footer_variables = extract_from_default_instance_name
         | 
| 24 24 |  | 
| 25 25 | 
             
                instance_name_options({}) do
         | 
| 26 26 | 
             
                  request
         | 
| 27 | 
            -
                   | 
| 27 | 
            +
                  assert_equal("Proc #{default_footer(*footer_variables)}",
         | 
| 28 | 
            +
                               response_header(DEFAULT_HEADER_NAME))
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              def test_header_name
         | 
| 33 | 
            +
                header_name = "X-header-name"
         | 
| 34 | 
            +
                footer_variables = extract_from_default_instance_name
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                instance_name_options(:header_name => header_name) do
         | 
| 37 | 
            +
                  request
         | 
| 38 | 
            +
                  assert_equal("Proc #{default_footer(*footer_variables)}",
         | 
| 39 | 
            +
                               response_header(header_name))
         | 
| 28 40 | 
             
                end
         | 
| 29 41 | 
             
              end
         | 
| 30 42 |  | 
| 31 43 | 
             
              def test_application_name
         | 
| 32 44 | 
             
                application_name = "HelloWorld"
         | 
| 33 | 
            -
                 | 
| 34 | 
            -
                user = default_instance_name.user
         | 
| 35 | 
            -
                revision = default_instance_name.revision
         | 
| 45 | 
            +
                footer_variables = extract_from_default_instance_name
         | 
| 36 46 |  | 
| 37 47 | 
             
                instance_name_options(:application_name => application_name) do
         | 
| 38 48 | 
             
                  request
         | 
| 39 | 
            -
                   | 
| 49 | 
            +
                  assert_equal("#{application_name} " +
         | 
| 50 | 
            +
                               "#{default_footer(*footer_variables)}",
         | 
| 51 | 
            +
                               response_header(DEFAULT_HEADER_NAME))
         | 
| 40 52 | 
             
                end
         | 
| 41 53 | 
             
              end
         | 
| 42 54 |  | 
| 43 55 | 
             
              def test_both_application_name_and_version
         | 
| 44 56 | 
             
                application_name = "HelloWorld"
         | 
| 45 57 | 
             
                version = 1
         | 
| 46 | 
            -
                 | 
| 47 | 
            -
                user = default_instance_name.user
         | 
| 48 | 
            -
                revision = default_instance_name.revision
         | 
| 58 | 
            +
                footer_variables = extract_from_default_instance_name
         | 
| 49 59 |  | 
| 50 60 | 
             
                instance_name_options(:application_name => application_name,
         | 
| 51 61 | 
             
                                      :version => version) do
         | 
| 52 62 | 
             
                  request
         | 
| 53 | 
            -
                   | 
| 63 | 
            +
                  assert_equal("#{application_name} v#{version} " +
         | 
| 64 | 
            +
                               "#{default_footer(*footer_variables)}",
         | 
| 65 | 
            +
                               response_header(DEFAULT_HEADER_NAME))
         | 
| 54 66 | 
             
                end
         | 
| 55 67 | 
             
              end
         | 
| 56 68 |  | 
| @@ -72,7 +84,25 @@ class InstanceNameTest < Test::Unit::TestCase | |
| 72 84 | 
             
              end
         | 
| 73 85 |  | 
| 74 86 | 
             
              def default_instance_name
         | 
| 75 | 
            -
                @default_instance_name ||= | 
| 87 | 
            +
                @default_instance_name ||=
         | 
| 88 | 
            +
                  create_instance_name(create_minimal_application).freeze
         | 
| 89 | 
            +
              end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
              def extract_from_default_instance_name
         | 
| 92 | 
            +
                server = default_instance_name.server
         | 
| 93 | 
            +
                user = default_instance_name.user
         | 
| 94 | 
            +
                revision = default_instance_name.revision
         | 
| 95 | 
            +
                branch = default_instance_name.branch
         | 
| 96 | 
            +
                ruby = default_instance_name.ruby
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                [server, user, revision, branch, ruby]
         | 
| 99 | 
            +
              end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
              def default_footer(server, user, revision, branch, ruby)
         | 
| 102 | 
            +
                footer = ""
         | 
| 103 | 
            +
                footer << "(at #{revision} (#{branch})) " if format_is_possible?(revision)
         | 
| 104 | 
            +
                footer << "on #{server} by #{user} with #{ruby}"
         | 
| 105 | 
            +
                footer
         | 
| 76 106 | 
             
              end
         | 
| 77 107 |  | 
| 78 108 | 
             
              def create_minimal_application
         | 
| @@ -92,7 +122,11 @@ class InstanceNameTest < Test::Unit::TestCase | |
| 92 122 | 
             
                yield
         | 
| 93 123 | 
             
              end
         | 
| 94 124 |  | 
| 95 | 
            -
              def  | 
| 96 | 
            -
                 | 
| 125 | 
            +
              def response_header(name)
         | 
| 126 | 
            +
                page.response_headers[name]
         | 
| 127 | 
            +
              end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
              def format_is_possible?(data)
         | 
| 130 | 
            +
                data and (data.respond_to?(:to_s) and not data.to_s.empty?)
         | 
| 97 131 | 
             
              end
         | 
| 98 132 | 
             
            end
         | 
| @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            # Copyright (C) 2010  Kouhei Sutou <kou@clear-code.com>
         | 
| 1 | 
            +
            # Copyright (C) 2010-2012  Kouhei Sutou <kou@clear-code.com>
         | 
| 2 2 | 
             
            #
         | 
| 3 3 | 
             
            # This library is free software; you can redistribute it and/or
         | 
| 4 4 | 
             
            # modify it under the terms of the GNU Lesser General Public
         | 
| @@ -12,7 +12,7 @@ | |
| 12 12 | 
             
            #
         | 
| 13 13 | 
             
            # You should have received a copy of the GNU Lesser General Public
         | 
| 14 14 | 
             
            # License along with this library; if not, write to the Free Software
         | 
| 15 | 
            -
            # Foundation, Inc.,  | 
| 15 | 
            +
            # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
         | 
| 16 16 |  | 
| 17 17 | 
             
            class MiddlewareJSONPTest < Test::Unit::TestCase
         | 
| 18 18 | 
             
              include RackngaTestUtils
         | 
| @@ -76,6 +76,18 @@ class MiddlewareJSONPTest < Test::Unit::TestCase | |
| 76 76 | 
             
                             @environment[@cache_key_key])
         | 
| 77 77 | 
             
              end
         | 
| 78 78 |  | 
| 79 | 
            +
              def test_jsonp_content_length
         | 
| 80 | 
            +
                @update_environment = Proc.new do |environment|
         | 
| 81 | 
            +
                  environment["Content-Length"] = @body.bytesize
         | 
| 82 | 
            +
                  environment
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
                visit("/?callback=jsonp_callback")
         | 
| 85 | 
            +
                expected_response = "jsonp_callback(#{@body});"
         | 
| 86 | 
            +
                assert_jsonp_response(expected_response)
         | 
| 87 | 
            +
                assert_equal(expected_response.bytesize.to_s,
         | 
| 88 | 
            +
                             page.response_headers["Content-Length"])
         | 
| 89 | 
            +
              end
         | 
| 90 | 
            +
             | 
| 79 91 | 
             
              private
         | 
| 80 92 | 
             
              def assert_jsonp_response(body)
         | 
| 81 93 | 
             
                assert_equal({
         | 
| @@ -0,0 +1,70 @@ | |
| 1 | 
            +
            # Copyright (C) 2011  Ryo Onodera <onodera@clear-code.com>
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # This library is free software; you can redistribute it and/or
         | 
| 4 | 
            +
            # modify it under the terms of the GNU Lesser General Public
         | 
| 5 | 
            +
            # License as published by the Free Software Foundation; either
         | 
| 6 | 
            +
            # version 2.1 of the License, or (at your option) any later version.
         | 
| 7 | 
            +
            #
         | 
| 8 | 
            +
            # This library is distributed in the hope that it will be useful,
         | 
| 9 | 
            +
            # but WITHOUT ANY WARRANTY; without even the implied warranty of
         | 
| 10 | 
            +
            # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
         | 
| 11 | 
            +
            # Lesser General Public License for more details.
         | 
| 12 | 
            +
            #
         | 
| 13 | 
            +
            # You should have received a copy of the GNU Lesser General Public
         | 
| 14 | 
            +
            # License along with this library; if not, write to the Free Software
         | 
| 15 | 
            +
            # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            class NginxRawURITest < Test::Unit::TestCase
         | 
| 18 | 
            +
              include RackngaTestUtils
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              class PseudoNginx
         | 
| 21 | 
            +
                def initialize(application)
         | 
| 22 | 
            +
                  @application = application
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def call(environment)
         | 
| 26 | 
            +
                  mimic_nginx_behavior(environment)
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  @application.call(environment)
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                private
         | 
| 32 | 
            +
                def mimic_nginx_behavior(environment)
         | 
| 33 | 
            +
                  environment["HTTP_X_RAW_REQUEST_URI"] = environment["PATH_INFO"]
         | 
| 34 | 
            +
                  environment["PATH_INFO"] = Rack::Utils.unescape(environment["PATH_INFO"])
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              def app
         | 
| 39 | 
            +
                application = Proc.new do |environment|
         | 
| 40 | 
            +
                  @environment = environment
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  response
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                raw_uri = Racknga::Middleware::NginxRawURI.new(application)
         | 
| 46 | 
            +
                pseudo_nginx = PseudoNginx.new(raw_uri)
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                pseudo_nginx
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
              def setup
         | 
| 52 | 
            +
                Capybara.app = app
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
              def test_slash
         | 
| 56 | 
            +
                path_info_with_slash = "/keywords/GNU%2fLinux"
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                visit(path_info_with_slash)
         | 
| 59 | 
            +
                assert_equal(path_info_with_slash, path_info)
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
              private
         | 
| 63 | 
            +
              def response
         | 
| 64 | 
            +
                [200, {"Content-Type" => "plain/text"}, ["this is a response."]]
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
              def path_info
         | 
| 68 | 
            +
                @environment["PATH_INFO"]
         | 
| 69 | 
            +
              end
         | 
| 70 | 
            +
            end
         | 
| @@ -12,7 +12,7 @@ | |
| 12 12 | 
             
            #
         | 
| 13 13 | 
             
            # You should have received a copy of the GNU Lesser General Public
         | 
| 14 14 | 
             
            # License along with this library; if not, write to the Free Software
         | 
| 15 | 
            -
            # Foundation, Inc.,  | 
| 15 | 
            +
            # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
         | 
| 16 16 |  | 
| 17 17 | 
             
            module MiddlewareRangeTests
         | 
| 18 18 | 
             
              include RackngaTestUtils
         |