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
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")