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
|