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.
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