racknga 0.9.2 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -12
  3. data/README.textile +9 -8
  4. data/Rakefile +19 -272
  5. data/doc/text/news.textile +20 -0
  6. data/lib/racknga/access_log_parser.rb +147 -0
  7. data/lib/racknga/api-keys.rb +40 -0
  8. data/lib/racknga/cache_database.rb +15 -5
  9. data/lib/racknga/exception_mail_notifier.rb +6 -6
  10. data/lib/racknga/log_database.rb +2 -1
  11. data/lib/racknga/log_entry.rb +85 -0
  12. data/lib/racknga/middleware/auth/api-key.rb +95 -0
  13. data/lib/racknga/middleware/cache.rb +22 -8
  14. data/lib/racknga/middleware/deflater.rb +13 -3
  15. data/lib/racknga/middleware/exception_notifier.rb +1 -2
  16. data/lib/racknga/middleware/instance_name.rb +92 -9
  17. data/lib/racknga/middleware/jsonp.rb +25 -5
  18. data/lib/racknga/middleware/log.rb +8 -3
  19. data/lib/racknga/middleware/nginx_raw_uri.rb +65 -0
  20. data/lib/racknga/middleware/range.rb +1 -1
  21. data/lib/racknga/reverse_line_reader.rb +1 -1
  22. data/lib/racknga/utils.rb +1 -1
  23. data/lib/racknga/version.rb +2 -2
  24. data/lib/racknga.rb +4 -2
  25. data/munin/plugins/passenger_application_ +61 -47
  26. data/munin/plugins/passenger_status +64 -33
  27. data/test/racknga-test-utils.rb +2 -1
  28. data/test/run-test.rb +1 -3
  29. data/test/{test-nginx-log-parser.rb → test-access-log-parser.rb} +115 -26
  30. data/test/test-api-keys.rb +80 -0
  31. data/test/test-middleware-auth-api-key.rb +144 -0
  32. data/test/test-middleware-cache.rb +1 -1
  33. data/test/test-middleware-instance-name.rb +50 -16
  34. data/test/test-middleware-jsonp.rb +14 -2
  35. data/test/test-middleware-nginx-raw-uri.rb +70 -0
  36. data/test/test-middleware-range.rb +1 -1
  37. metadata +159 -155
  38. data/lib/racknga/nginx_access_log_parser.rb +0 -139
  39. 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
19
 
20
20
  require 'stringio'
21
21
 
22
- module NginxAccessLogParserTests
22
+ module AccessLogParserTests
23
23
  module Data
24
24
  private
25
- def time_log_component
26
- times = ["03/Aug/2011:16:58:01 +0900", runtime, request_time].compact
27
- "[#{times.join(', ')}]"
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
- "\"GET / HTTP/1.1\" 200 613 \"-\" \"Ruby\""
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
- "\"GET /the-truth.html HTTP/1.1\" 404 613 \"-\" \"Ruby\""
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
- "\"GET #{path} HTTP/1.1\" 200 613 \"-\" \"Ruby\""
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
- "\"GET #{path} HTTP/1.1\" 200 613 \"-\" \"Ruby\""
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::NginxAccessLogParser.new(file)
149
+ Racknga::AccessLogParser.new(file)
114
150
  end
115
151
 
116
152
  def create_reversed_log_parser(file)
117
- Racknga::ReversedNginxAccessLogParser.new(file)
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 test_usual_nginx_access_log
176
+ def test_usual_log
141
177
  accesses = parse(join_lines(usual_log_line))
142
- access = accesses.first
143
- assert_equal(usual_log_entry, access)
178
+ assert_equal([usual_log_entry],
179
+ accesses)
144
180
  end
145
181
 
146
- def test_no_access_log
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 test_multiple_nginx_access_log
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 test_reversed_nginx_access_log
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 test_bad_nginx_access_log
172
- assert_raise(Racknga::NginxAccessLogParser::FormatError) do
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 CombinedWithTimeLogTest < Test::Unit::TestCase
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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
- server = default_instance_name.server
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
- assert_header("Proc (at #{revision}) on #{server} by #{user}")
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
- server = default_instance_name.server
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
- assert_header("#{application_name} (at #{revision}) on #{server} by #{user}")
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
- server = default_instance_name.server
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
- assert_header("#{application_name} v#{version} (at #{revision}) on #{server} by #{user}")
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 ||= create_instance_name(create_minimal_application).freeze
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 assert_header(expected_header)
96
- assert_equal(expected_header, page.response_headers["X-Responsed-By"])
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
  module MiddlewareRangeTests
18
18
  include RackngaTestUtils