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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cd550e89e845e0e90ccac2ef34bf3823e03639b0d61e71fe75ee02bb9ad63e2a
4
+ data.tar.gz: 4365f32450b7b0a9fc95b77cfbe3403119b8f2623824f3b4be199ec594255011
5
+ SHA512:
6
+ metadata.gz: a1d84e5281d56bd2f520d0483f1a9ba6cdd1dafbc363268e466b4fea860dd832892d7b5d84ec9ba6d38ebc74d5d356603e7857543ea21029a512fa0b1cd438ae
7
+ data.tar.gz: f983eab4c092d7d2215d2d52310ff51dc3568be0fb197444f4a5f0a8a7c36ef806cb45a2451b38636994d9fac6d53cda6ca07008d91f0d18557cf5f2d8ff0fc9
data/Gemfile CHANGED
@@ -1,6 +1,7 @@
1
1
  # -*- mode: ruby; coding: utf-8 -*-
2
2
  #
3
3
  # Copyright (C) 2011 Kouhei Sutou <kou@clear-code.com>
4
+ # Copyright (C) 2013 Haruka Yoshihara <yoshihara@clear-code.com>
4
5
  #
5
6
  # This library is free software; you can redistribute it and/or
6
7
  # modify it under the terms of the GNU Lesser General Public
@@ -13,18 +14,8 @@
13
14
  #
14
15
  # You should have received a copy of the GNU Lesser General Public
15
16
  # License along with this library; if not, write to the Free Software
16
- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
18
 
18
19
  source "http://rubygems.org/"
19
20
 
20
- gem "rroonga"
21
- gem "rack"
22
-
23
- group :development, :test do
24
- gem "test-unit"
25
- gem "test-unit-notify"
26
- gem "test-unit-capybara"
27
- gem "rake"
28
- gem "jeweler"
29
- gem "yard"
30
- end
21
+ gemspec
data/README.textile CHANGED
@@ -2,15 +2,15 @@ h1. README
2
2
 
3
3
  h2. Name
4
4
 
5
- racknga
5
+ Racknga
6
6
 
7
7
  h2. Description
8
8
 
9
- Rack middlewares that use rroonga features and
10
- middlewares/utilities that don't use rroonga features.
9
+ Rack middlewares that use Rroonga features and
10
+ middlewares/utilities that don't use Rroonga features.
11
11
 
12
- * "rroonga":http://groonga.rubyforge.org/
13
- * "Rack":http://rack.rubyforge.org/
12
+ * "Rroonga":http://ranguba.org/
13
+ * "Rack":http://rack.github.io/
14
14
 
15
15
  h2. Authors
16
16
 
@@ -26,7 +26,7 @@ including contributed patches.)
26
26
  h2. Dependencies
27
27
 
28
28
  * Ruby >= 1.9.1
29
- * rroonga
29
+ * Rroonga
30
30
  * Rack
31
31
 
32
32
  h2. Suggested libraries
@@ -41,11 +41,12 @@ h2. Install
41
41
 
42
42
  h2. Documents
43
43
 
44
- http://groonga.rubyforge.org/racknga/en/
44
+ http://ranguba.org/racknga/en/
45
45
 
46
46
  h2. Mailing list
47
47
 
48
- http://rubyforge.org/mailman/listinfo/groonga-users-en
48
+ * English: "groonga-talk":http://lists.sourceforge.net/mailman/listinfo/groonga-talk
49
+ * Japanese: "groonga-dev":http://lists.sourceforge.jp/mailman/listinfo/groonga-dev
49
50
 
50
51
  h2. Thanks
51
52
 
data/Rakefile CHANGED
@@ -13,7 +13,7 @@
13
13
  #
14
14
  # You should have received a copy of the GNU Lesser General Public
15
15
  # License along with this library; if not, write to the Free Software
16
- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
 
18
18
  require 'English'
19
19
 
@@ -21,289 +21,36 @@ require 'fileutils'
21
21
  require 'pathname'
22
22
  require 'erb'
23
23
  require 'rubygems'
24
- require 'jeweler'
25
- require "rake/clean"
26
- require "yard"
24
+ require 'rubygems/package_task'
25
+ require 'bundler/gem_helper'
26
+ require "packnga"
27
27
 
28
28
  base_dir = Pathname.new(__FILE__).dirname
29
29
  racknga_lib_dir = base_dir + 'lib'
30
30
  $LOAD_PATH.unshift(racknga_lib_dir.to_s)
31
31
 
32
- def guess_version
33
- require 'racknga/version'
34
- Racknga::VERSION
32
+ helper = Bundler::GemHelper.new(base_dir)
33
+ def helper.version_tag
34
+ version
35
35
  end
36
+ helper.install
37
+ spec = helper.gemspec
36
38
 
37
- ENV["VERSION"] ||= guess_version
38
- version = ENV["VERSION"].dup
39
- project = nil
40
- spec = nil
41
- Jeweler::Tasks.new do |_spec|
42
- spec = _spec
43
- spec.name = 'racknga'
44
- spec.version = version
45
- spec.rubyforge_project = 'groonga'
46
- spec.homepage = "http://groonga.rubyforge.org/"
47
- authors_file = File.join(base_dir, "AUTHORS")
48
- authors = []
49
- emails = []
50
- File.readlines(authors_file).each do |line|
51
- if /\s*<([^<>]*)>$/ =~ line
52
- authors << $PREMATCH
53
- emails << $1
54
- end
55
- end
56
- spec.authors = authors
57
- spec.email = emails
58
- spec.summary = "A Rack middleware collection for rroonga features."
59
- spec.description = <<-EOD.gsub(/\n/, ' ').strip
60
- Racknga is a Rack middlewares that uses rroonga features.
61
- EOD
62
- spec.license = "LGPLv2.1 or later"
63
- spec.files = FileList["lib/**/*.rb",
64
- "{license,munin,doc/text/}/**/*",
65
- "example/*.rb",
66
- "AUTHORS",
67
- "Rakefile",
68
- "Gemfile",
69
- "README*"]
70
- spec.test_files = FileList["test/**/*.rb"]
39
+ Gem::PackageTask.new(spec) do |pkg|
40
+ pkg.need_tar_gz = true
71
41
  end
72
42
 
73
- Rake::Task["release"].prerequisites.clear
74
- Jeweler::RubygemsDotOrgTasks.new do
43
+ Packnga::DocumentTask.new(spec) do |task|
44
+ task.original_language = "en"
45
+ task.translate_languages = ["ja"]
75
46
  end
76
47
 
77
- reference_base_dir = Pathname.new("doc/reference")
78
- doc_en_dir = reference_base_dir + "en"
79
- html_base_dir = Pathname.new("doc/html")
80
- html_reference_dir = html_base_dir + spec.name
81
- YARD::Rake::YardocTask.new do |task|
82
- task.options += ["--title", spec.name]
83
- task.options += ["--readme", "README.textile"]
84
- task.options += ["--files", "doc/text/**/*"]
85
- task.options += ["--output-dir", doc_en_dir.to_s]
86
- task.options += ["--charset", "utf-8"]
48
+ Packnga::ReleaseTask.new(spec) do
87
49
  end
88
50
 
89
- task :yard do
90
- doc_en_dir.find do |path|
91
- next if path.extname != ".html"
92
- html = path.read
93
- html = html.gsub(/<div id="footer">.+<\/div>/m,
94
- "<div id=\"footer\"></div>")
95
- path.open("w") do |html_file|
96
- html_file.print(html)
97
- end
98
- end
51
+ desc "Run test"
52
+ task :test do
53
+ ruby("-rubygems", "test/run-test.rb")
99
54
  end
100
55
 
101
- include ERB::Util
102
-
103
- def apply_template(content, paths, templates, language)
104
- content = content.sub(/lang="en"/, "lang=\"#{language}\"")
105
-
106
- title = nil
107
- content = content.sub(/<title>(.+?)<\/title>/m) do
108
- title = $1
109
- templates[:head].result(binding)
110
- end
111
-
112
- content = content.sub(/<body(?:.*?)>/) do |body_start|
113
- "#{body_start}\n#{templates[:header].result(binding)}\n"
114
- end
115
-
116
- content = content.sub(/<\/body/) do |body_end|
117
- "\n#{templates[:footer].result(binding)}\n#{body_end}"
118
- end
119
-
120
- content
121
- end
122
-
123
- def erb_template(name)
124
- file = File.join("doc/templates", "#{name}.html.erb")
125
- template = File.read(file)
126
- erb = ERB.new(template, nil, "-")
127
- erb.filename = file
128
- erb
129
- end
130
-
131
- def rsync_to_rubyforge(spec, source, destination, options={})
132
- config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml")))
133
- host = "#{config["username"]}@rubyforge.org"
134
-
135
- rsync_args = "-av --exclude '*.erb' --chmod=ug+w"
136
- rsync_args << " --delete" if options[:delete]
137
- remote_dir = "/var/www/gforge-projects/#{spec.rubyforge_project}/"
138
- sh("rsync #{rsync_args} #{source} #{host}:#{remote_dir}#{destination}")
139
- end
140
-
141
- def rake(*arguments)
142
- ruby($0, *arguments)
143
- end
144
-
145
- namespace :reference do
146
- translate_languages = [:ja]
147
- supported_languages = [:en, *translate_languages]
148
- html_files = FileList[doc_en_dir + "**/*.html"].to_a
149
-
150
- directory reference_base_dir.to_s
151
- CLOBBER.include(reference_base_dir.to_s)
152
-
153
- po_dir = "doc/po"
154
- pot_file = "#{po_dir}/#{spec.name}.pot"
155
- namespace :pot do
156
- directory po_dir
157
- file pot_file => [po_dir, *html_files] do |t|
158
- sh("xml2po", "--keep-entities", "--output", t.name, *html_files)
159
- end
160
-
161
- desc "Generates pot file."
162
- task :generate => pot_file
163
- end
164
-
165
- namespace :po do
166
- translate_languages.each do |language|
167
- namespace language do
168
- po_file = "#{po_dir}/#{language}.po"
169
-
170
- if File.exist?(po_file)
171
- file po_file => html_files do |t|
172
- sh("xml2po", "--keep-entities", "--update", t.name, *html_files)
173
- end
174
- else
175
- file po_file => pot_file do |t|
176
- sh("msginit",
177
- "--input=#{pot_file}",
178
- "--output=#{t.name}",
179
- "--locale=#{language}")
180
- end
181
- end
182
-
183
- desc "Updates po file for #{language}."
184
- task :update => po_file
185
- end
186
- end
187
-
188
- desc "Updates po files."
189
- task :update do
190
- rake("clobber")
191
- rake("yard")
192
- translate_languages.each do |language|
193
- rake("reference:po:#{language}:update")
194
- end
195
- end
196
- end
197
-
198
- namespace :translate do
199
- translate_languages.each do |language|
200
- po_file = "#{po_dir}/#{language}.po"
201
- translate_doc_dir = "#{reference_base_dir}/#{language}"
202
-
203
- desc "Translates documents to #{language}."
204
- task language => [po_file, reference_base_dir, *html_files] do
205
- doc_en_dir.find do |path|
206
- base_path = path.relative_path_from(doc_en_dir)
207
- translated_path = "#{translate_doc_dir}/#{base_path}"
208
- if path.directory?
209
- mkdir_p(translated_path)
210
- next
211
- end
212
- case path.extname
213
- when ".html"
214
- sh("xml2po --keep-entities " +
215
- "--po-file #{po_file} --language #{language} " +
216
- "#{path} > #{translated_path}")
217
- else
218
- cp(path.to_s, translated_path, :preserve => true)
219
- end
220
- end
221
- end
222
- end
223
- end
224
-
225
- translate_task_names = translate_languages.collect do |language|
226
- "reference:translate:#{language}"
227
- end
228
- desc "Translates references."
229
- task :translate => translate_task_names
230
-
231
- desc "Generates references."
232
- task :generate => [:yard, :translate]
233
-
234
- namespace :publication do
235
- task :prepare do
236
- supported_languages.each do |language|
237
- raw_reference_dir = reference_base_dir + language.to_s
238
- prepared_reference_dir = html_reference_dir + language.to_s
239
- rm_rf(prepared_reference_dir.to_s)
240
- head = erb_template("head.#{language}")
241
- header = erb_template("header.#{language}")
242
- footer = erb_template("footer.#{language}")
243
- raw_reference_dir.find do |path|
244
- relative_path = path.relative_path_from(raw_reference_dir)
245
- prepared_path = prepared_reference_dir + relative_path
246
- if path.directory?
247
- mkdir_p(prepared_path.to_s)
248
- else
249
- case path.basename.to_s
250
- when /(?:file|method|class)_list\.html\z/
251
- cp(path.to_s, prepared_path.to_s)
252
- when /\.html\z/
253
- relative_dir_path = relative_path.dirname
254
- current_path = relative_dir_path + path.basename
255
- if current_path.basename.to_s == "index.html"
256
- current_path = current_path.dirname
257
- end
258
- top_path = html_base_dir.relative_path_from(prepared_path.dirname)
259
- package_path = top_path + spec.name
260
- paths = {
261
- :top => top_path,
262
- :current => current_path,
263
- :package => package_path,
264
- }
265
- templates = {
266
- :head => head,
267
- :header => header,
268
- :footer => footer
269
- }
270
- content = apply_template(File.read(path.to_s),
271
- paths,
272
- templates,
273
- language)
274
- File.open(prepared_path.to_s, "w") do |file|
275
- file.print(content)
276
- end
277
- else
278
- cp(path.to_s, prepared_path.to_s)
279
- end
280
- end
281
- end
282
- end
283
- File.open("#{html_reference_dir}/.htaccess", "w") do |file|
284
- file.puts("RedirectMatch permanent ^/#{spec.name}/$ " +
285
- "#{spec.homepage}#{spec.name}/en/")
286
- end
287
- end
288
- end
289
-
290
- desc "Upload document to rubyforge."
291
- task :publish => [:generate, "reference:publication:prepare"] do
292
- rsync_to_rubyforge(spec, "#{html_reference_dir}/", spec.name)
293
- end
294
- end
295
-
296
- namespace :html do
297
- desc "Publish HTML to Web site."
298
- task :publish do
299
- rsync_to_rubyforge(spec, "#{html_base_dir}/", "")
300
- end
301
- end
302
-
303
- desc "Upload document to rubyforge."
304
- task :publish => ["reference:publish"]
305
-
306
- desc "Tag the current revision."
307
- task :tag do
308
- sh("git tag -a #{version} -m 'release #{version}!!!'")
309
- end
56
+ task :default => :test
@@ -1,5 +1,25 @@
1
1
  h1. NEWS
2
2
 
3
+ h2. 0.9.4: 2023-09-03
4
+
5
+ h3. Improvments
6
+
7
+ * [cache] Made Rroonga dependency optional. Users must add Rroonga
8
+ dependency explicitly.
9
+ * And more improvements...
10
+
11
+ h2. 0.9.3: 2011-11-12
12
+
13
+ h3. Improvments
14
+
15
+ * [access-log-parser] Supported Apache log.
16
+ * [cache] Fixed unknown name errors.
17
+ * [cache] Fixed max age.
18
+ * [nginx] Added NginxRawURI middleware.
19
+ * [instance-name] Added branch name and Ruby version.
20
+ * [exception-mail-notifier] Used #message instead of #to_s.
21
+ * [logger] Logged also X-Runtime.
22
+
3
23
  h2. 0.9.2: 2011-08-07
4
24
 
5
25
  h3. Improvments
@@ -0,0 +1,147 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2011 Ryo Onodera <onodera@clear-code.com>
4
+ # Copyright (C) 2011 Kouhei Sutou <kou@clear-code.com>
5
+ #
6
+ # This library is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License as published by the Free Software Foundation; either
9
+ # version 2.1 of the License, or (at your option) any later version.
10
+ #
11
+ # This library is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+
20
+ require "racknga/log_entry"
21
+ require "racknga/reverse_line_reader"
22
+
23
+ module Racknga
24
+ # Supported formats:
25
+ # * combined (nginx's default format)
26
+ # * combined (Apache's predefined format)
27
+ # * combined_with_time_nginx (custom format with runtime)
28
+ # * combined_with_time_apache (custom format with runtime)
29
+ #
30
+ # Configurations:
31
+ # * combined
32
+ # * nginx
33
+ # log_format combined '$remote_addr - $remote_user [$time_local] '
34
+ # '"$request" $status $body_bytes_sent '
35
+ # '"$http_referer" "$http_user_agent"';
36
+ # access_log log/access.log combined
37
+ # * Apache
38
+ # CustomLog ${APACHE_LOG_DIR}/access.log combined
39
+ #
40
+ # * combined_with_time_nginx
41
+ # * nginx
42
+ # log_format combined_with_time '$remote_addr - $remote_user '
43
+ # '[$time_local, $upstream_http_x_runtime, $request_time] '
44
+ # '"$request" $status $body_bytes_sent '
45
+ # '"$http_referer" "$http_user_agent"';
46
+ # access_log log/access.log combined_with_time
47
+ #
48
+ # * combined_with_time_apache
49
+ # * Apache
50
+ # LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\" %{X-Runtime}o %D" combined_with_time
51
+ # CustomLog ${APACHE_LOG_DIR}/access.log combined_with_time
52
+ class AccessLogParser
53
+ include Enumerable
54
+
55
+ class FormatError < StandardError
56
+ end
57
+
58
+ def initialize(line_reader)
59
+ @line_reader = line_reader
60
+ end
61
+
62
+ def each
63
+ @line_reader.each do |line|
64
+ line.force_encoding("UTF-8")
65
+ yield(parse_line(line)) if line.valid_encoding?
66
+ end
67
+ end
68
+
69
+ private
70
+ REMOTE_ADDRESS = "[^\\x20]+"
71
+ REMOTE_USER = "[^\\x20]+"
72
+ TIME_LOCAL = "[^\\x20]+\\x20\\+\\d{4}"
73
+ RUNTIME = "(?:[\\d.]+|-)"
74
+ REQUEST_TIME = "[\\d.]+"
75
+ REQUEST = ".*?"
76
+ STATUS = "\\d{3}"
77
+ BODY_BYTES_SENT = "(?:\\d+|-)"
78
+ HTTP_REFERER = ".*?"
79
+ HTTP_USER_AGENT = "(?:\\\"|[^\"])*?"
80
+ COMBINED_FORMAT =
81
+ /^(#{REMOTE_ADDRESS})\x20
82
+ -\x20
83
+ (#{REMOTE_USER})\x20
84
+ \[(#{TIME_LOCAL})(?:,\x20(.+))?\]\x20+
85
+ "(#{REQUEST})"\x20
86
+ (#{STATUS})\x20
87
+ (#{BODY_BYTES_SENT})\x20
88
+ "(#{HTTP_REFERER})"\x20
89
+ "(#{HTTP_USER_AGENT})"
90
+ (?:\x20(.+))?$/x
91
+ def parse_line(line)
92
+ case line
93
+ when COMBINED_FORMAT
94
+ last_match = Regexp.last_match
95
+ options = {}
96
+ options[:remote_address] = last_match[1]
97
+ options[:remote_user] = last_match[2]
98
+ options[:time_local] = parse_local_time(last_match[3])
99
+ if last_match[4]
100
+ if /\A(#{RUNTIME}), (#{REQUEST_TIME})\z/ =~ last_match[4]
101
+ time_match = Regexp.last_match
102
+ options[:runtime] = time_match[1]
103
+ options[:request_time] = time_match[2]
104
+ else
105
+ message = "expected 'RUNTIME, REQUEST_TIME' time format: " +
106
+ "<#{last_match[4]}>: <#{line}>"
107
+ raise FormatError.new(message)
108
+ end
109
+ end
110
+ options[:request] = last_match[5]
111
+ options[:status] = last_match[6].to_i
112
+ options[:body_bytes_sent] = last_match[7]
113
+ options[:http_referer] = last_match[8]
114
+ options[:http_user_agent] = last_match[9]
115
+ if last_match[10]
116
+ if /\A(#{RUNTIME}) (#{REQUEST_TIME})\z/ =~ last_match[10]
117
+ time_match = Regexp.last_match
118
+ runtime = time_match[1]
119
+ request_time = time_match[2]
120
+ request_time = request_time.to_i * 0.000_001 if request_time
121
+ options[:runtime] = runtime
122
+ options[:request_time] = request_time
123
+ else
124
+ message = "expected 'RUNTIME REQUEST_TIME' time format: " +
125
+ "<#{last_match[10]}>: <#{line}>"
126
+ raise FormatError.new(message)
127
+ end
128
+ end
129
+ LogEntry.new(options)
130
+ else
131
+ raise FormatError.new("unsupported format log entry: <#{line}>")
132
+ end
133
+ end
134
+
135
+ def parse_local_time(token)
136
+ day, month, year, hour, minute, second, _time_zone = token.split(/[\/: ]/)
137
+ _ = _time_zone # FIXME: suppress a warning. :<
138
+ Time.local(year, month, day, hour, minute, second)
139
+ end
140
+ end
141
+
142
+ class ReversedAccessLogParser < AccessLogParser
143
+ def initialize(line_reader)
144
+ @line_reader = ReverseLineReader.new(line_reader)
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,40 @@
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
+ module Racknga
20
+ # This is a store for API keys. It is used with
21
+ # Racknga::Middleware::Auth::APIKeys.
22
+ class APIKeys
23
+ # @param [String] query_parameter query parameter to specify an API key.
24
+ # @param [Array] api_keys stored API keys.
25
+ def initialize(query_parameter, api_keys)
26
+ @query_parameter = query_parameter
27
+ @api_keys = api_keys
28
+ end
29
+
30
+ # Checks whether stored API keys includes an API key in a request.
31
+ # @param [Hash] environment an environment for Rack.
32
+ # @return [Boolean] true if an API key is included, or false if not.
33
+ def include?(environment)
34
+ request = Rack::Request.new(environment)
35
+ key = request[@query_parameter]
36
+
37
+ @api_keys.include?(key)
38
+ end
39
+ end
40
+ end
@@ -14,7 +14,7 @@
14
14
  #
15
15
  # You should have received a copy of the GNU Lesser General Public
16
16
  # License along with this library; if not, write to the Free Software
17
- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
18
 
19
19
  require 'fileutils'
20
20
 
@@ -53,17 +53,27 @@ module Racknga
53
53
  # process from your Rack application
54
54
  # process. (e.g. cron.) It's multi process safe.
55
55
  def purge_old_responses
56
- age_modulo = 2 ** 32
56
+ age_modulo = 2 ** 31 - 1
57
57
  age = configuration.age
58
58
  previous_age = (age - 1).modulo(age_modulo)
59
- configuration.age = (age + 1).modulo(age_modulo)
59
+ next_age = (age + 1).modulo(age_modulo)
60
60
 
61
61
  target_responses = responses.select do |record|
62
- record.age == previous_age
62
+ record.age == next_age
63
63
  end
64
64
  target_responses.each do |response|
65
65
  response.key.delete
66
66
  end
67
+ configuration.age = next_age
68
+
69
+ target_responses = responses.select do |record|
70
+ record.age <= previous_age
71
+ end
72
+ target_responses.each do |response|
73
+ response.key.delete
74
+ end
75
+
76
+ responses.defrag if responses.respond_to?(:defrag)
67
77
  end
68
78
 
69
79
  def ensure_database
@@ -88,7 +98,7 @@ module Racknga
88
98
  :key_type => "ShortText") do |table|
89
99
  table.uint32("status")
90
100
  table.short_text("headers")
91
- table.text("body", :compress => :zlib)
101
+ table.text("body")
92
102
  table.short_text("checksum")
93
103
  table.uint32("age")
94
104
  table.time("created_at")