regurgitator 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog CHANGED
@@ -1,5 +1,69 @@
1
1
  ChangeLog from http://bogomips.org/regurgitator.git
2
2
 
3
+ commit 84e48c63074049f32660672b5a3c195d12dc3896
4
+ Author: Eric Wong <normalperson@yhbt.net>
5
+ Date: Fri Nov 11 08:46:12 2011 +0000
6
+
7
+ regurgitator 0.1.0
8
+
9
+ * local_file: support HTTP Range: requests
10
+ * minor code cleanups
11
+ * update/fix install dependencies (include rpatricia)
12
+
13
+ commit 341b4d3198013893ae9929d588cfde73fa39b2ee
14
+ Author: Eric Wong <e@yhbt.net>
15
+ Date: Fri Nov 11 08:33:40 2011 +0000
16
+
17
+ local_file: support HTTP Range: requests
18
+
19
+ This should give local users Range: functionality since most
20
+ HTTP servers used for MogileFS storage support Range:, too.
21
+ For requests that require proxying back to the HTTP server,
22
+ this we've always forwarded Range: requests and Content-Range:
23
+ responses as-is in a completely agnostic manner.
24
+
25
+ commit a898550de8398fafef9690f29568fffe351df68b
26
+ Author: Eric Wong <normalperson@yhbt.net>
27
+ Date: Fri Nov 11 08:22:58 2011 +0000
28
+
29
+ bump dependencies
30
+
31
+ This forces newer kgio and newer http_spew on people, and
32
+ we'll need the latest rack for Range: parsing.
33
+
34
+ commit 6cb4d49092eceee6720a702ca51f96851711b612
35
+ Author: Eric Wong <normalperson@yhbt.net>
36
+ Date: Fri Oct 21 17:41:03 2011 -0700
37
+
38
+ use raise instead of abort in case we hit bugs
39
+
40
+ These should probably nuke the process, but we'll be nice
41
+ and raise instead since we shouldn't cause data corruption.
42
+
43
+ commit 70f8be5607ecdf087e20c0f539e6cac9c8b6bc16
44
+ Author: Eric Wong <normalperson@yhbt.net>
45
+ Date: Fri Jun 24 18:00:01 2011 -0700
46
+
47
+ test_local: use Dir.mktmpdir
48
+
49
+ The "tmpdir" module in the standhas a handy method for creating tmpdirs
50
+
51
+ commit 752fdf60e8ac560d07a0e2f7d3ee58f075c620b9
52
+ Author: Eric Wong <normalperson@yhbt.net>
53
+ Date: Fri Jun 24 17:56:38 2011 -0700
54
+
55
+ less initialize/super magic
56
+
57
+ It's making things too hard to keep track of
58
+
59
+ commit 7d826aae4753eb9eeca3467accb2c13eabd4a8eb
60
+ Author: Eric Wong <normalperson@yhbt.net>
61
+ Date: Wed May 18 16:38:51 2011 -0700
62
+
63
+ gemspec: add rpatricia dependency
64
+
65
+ Not everybody has this gem installed by default :x
66
+
3
67
  commit 0104cfec9974cc65d79ce614ab37ba3fbd672b11
4
68
  Author: Eric Wong <normalperson@yhbt.net>
5
69
  Date: Tue May 10 15:09:50 2011 -0700
data/GIT-VERSION-FILE CHANGED
@@ -1 +1 @@
1
- GIT_VERSION = 0.0.0
1
+ GIT_VERSION = 0.1.0
data/GIT-VERSION-GEN CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
3
  GVF=GIT-VERSION-FILE
4
- DEF_VER=v0.0.0.GIT
4
+ DEF_VER=v0.1.0.GIT
5
5
 
6
6
  LF='
7
7
  '
data/LATEST CHANGED
@@ -1 +1,6 @@
1
- Currently unreleased
1
+ === regurgitator 0.1.0 / 2011-11-11 08:47 UTC
2
+
3
+ * local_file: support HTTP Range: requests
4
+ * minor code cleanups
5
+ * update/fix install dependencies (include rpatricia)
6
+
data/NEWS CHANGED
@@ -1 +1,6 @@
1
- No news yet.
1
+ === regurgitator 0.1.0 / 2011-11-11 08:47 UTC
2
+
3
+ * local_file: support HTTP Range: requests
4
+ * minor code cleanups
5
+ * update/fix install dependencies (include rpatricia)
6
+
@@ -14,19 +14,15 @@ module Regurgitator::Device
14
14
  DEVICES_ON = 'SELECT devid FROM file_on WHERE fid = ?'
15
15
  # :startdoc:
16
16
 
17
- def initialize(*args) # :nodoc:
18
- super
19
- init_device_ivars
20
- end
21
-
22
- def init_device_ivars
17
+ def device_init
18
+ server_settings_init
23
19
  @device_cache_mtime = Time.at(0)
24
20
  @device_cache = nil
25
21
  @device_cache_lock = Mutex.new
26
22
  end
27
23
 
28
24
  def self.extended(obj)
29
- obj.init_device_ivars
25
+ obj.device_init
30
26
  end
31
27
 
32
28
  def device_uri_pair!(opts, get_port)
@@ -4,8 +4,7 @@ module Regurgitator::Domain
4
4
 
5
5
  REFRESH_DOMAIN = 'SELECT dmid,namespace FROM domain' # :nodoc:
6
6
 
7
- def initialize(*args) # :nodoc:
8
- super
7
+ def domain_init
9
8
  @domain_lock = Mutex.new
10
9
  @domain_cache_mtime = Time.at(0)
11
10
  @domain_cache = nil
@@ -27,7 +27,7 @@ class Regurgitator::DomainHost
27
27
  raise TypeError, ":suffix must be a String or Regexp #{suffix.inspect}"
28
28
  end
29
29
  @domain_regexp = suffix
30
- super(app, opts[:db])
30
+ endpoint_init(app, opts[:db])
31
31
  end
32
32
 
33
33
  def call(env) # :nodoc:
@@ -28,6 +28,6 @@ class Regurgitator::DomainPath
28
28
  end
29
29
 
30
30
  def initialize(app, db) # :nodoc:
31
- super(app, Hash === db ? db[:db] : db)
31
+ endpoint_init(app, Hash === db ? db[:db] : db)
32
32
  end
33
33
  end
@@ -7,10 +7,10 @@ module Regurgitator::Endpoint
7
7
 
8
8
  REPROXY_KEY = Regurgitator::REPROXY_KEY # :nodoc:
9
9
 
10
- def initialize(app, db)
10
+ def endpoint_init(app, db)
11
11
  @app = app
12
12
  @db = db
13
- super
13
+ file_info_init
14
14
  end
15
15
 
16
16
  def best_addr(env)
@@ -87,7 +87,7 @@ module Regurgitator::Endpoint
87
87
  body.close if body.respond_to?(:close)
88
88
  return [ status, headers, [] ]
89
89
  else
90
- abort "Unexpected REQUEST_METHOD=#{env['REQUEST_METHOD']}"
90
+ raise "BUG: Unexpected REQUEST_METHOD=#{env['REQUEST_METHOD']}"
91
91
  end
92
92
  rescue Regurgitator::NoDevices
93
93
  retry unless zone_uris.empty?
@@ -5,6 +5,11 @@ module Regurgitator::FileInfo
5
5
 
6
6
  # :stopdoc:
7
7
  FILE_INFO = 'SELECT fid,length FROM file WHERE dmid = ? AND dkey = ? LIMIT 1'
8
+
9
+ def file_info_init
10
+ domain_init
11
+ device_init
12
+ end
8
13
  # :startdoc:
9
14
 
10
15
  # returns a hash with file information and URIs for accessing the file:
@@ -55,7 +55,7 @@ module Regurgitator::Local
55
55
  Regurgitator::Local.include?(uri.host) or return
56
56
  (roots = STORE_PATHS[uri.port]).empty? and return
57
57
  uri.path =~ %r{\A/(dev\d+)/} or
58
- abort "BUG: path needs to match '\\A/dev\d+/' (#{uri})"
58
+ raise "BUG: path needs to match '\\A/dev\d+/' (#{uri})"
59
59
  devN = $1
60
60
  rv = nil
61
61
  roots.each do |root, dev_dirs|
@@ -18,12 +18,30 @@ class Regurgitator::LocalFile
18
18
  if modified_since = env["HTTP_IF_MODIFIED_SINCE"]
19
19
  modified_since?(modified_since, stat) or return
20
20
  end
21
+ size = stat.size
22
+
23
+ headers = {
24
+ "Content-Type" => "application/octet-stream", # always ".fid"
25
+ "Content-Length" => size.to_s,
26
+ "Last-Modified" => stat.mtime.httpdate,
27
+ "Accept-Ranges" => "bytes",
28
+ }
29
+ @response = [ 200, headers ]
30
+
31
+ ranges = Rack::Utils.byte_ranges(env, size)
32
+ if nil == ranges || ranges.size > 1
33
+ @range = nil
34
+ elsif @range = ranges[0]
35
+ @response[0] = 206
36
+ headers["Content-Range"] = "bytes #{@range.begin}-#{@range.end}/#{size}"
37
+ headers["Content-Length"] = (@range.end - @range.begin + 1).to_s
38
+ else
39
+ @response[0] = 416
40
+ headers["Content-Range"] = "bytes */#{size}"
41
+ @response << []
42
+ return
43
+ end
21
44
 
22
- @response = [ 200, {
23
- "Content-Type" => "application/octet-stream", # always ".fid"
24
- "Content-Length" => stat.size.to_s,
25
- "Last-Modified" => stat.mtime.httpdate,
26
- } ]
27
45
  case env["REQUEST_METHOD"]
28
46
  when "GET"
29
47
  @to_path, @uri = path, uri
@@ -31,17 +49,27 @@ class Regurgitator::LocalFile
31
49
  when "HEAD"
32
50
  @response << []
33
51
  else
34
- abort "Unexpected REQUEST_METHOD=#{env['REQUEST_METHOD']}"
52
+ raise "BUG: Unexpected REQUEST_METHOD=#{env['REQUEST_METHOD']}"
35
53
  end
36
54
  end
37
55
 
38
56
  # normal Rack HTTP server endpoint, used if the server can't handle
39
57
  # +to_path+
40
58
  def each
41
- buf = ""
42
59
  File.open(@to_path) do |fp|
43
- while fp.read(0x4000, buf)
44
- yield buf
60
+ buf = ""
61
+ max = 0x4000
62
+ if @range
63
+ fp.seek(@range.begin)
64
+ len = @range.end - @range.begin + 1
65
+ while len > 0 && fp.read(len > max ? max : len, buf)
66
+ len -= buf.size
67
+ yield buf
68
+ end
69
+ else
70
+ while fp.read(0x4000, buf)
71
+ yield buf
72
+ end
45
73
  end
46
74
  end
47
75
  end
@@ -19,7 +19,7 @@ class Regurgitator::OneDomain
19
19
 
20
20
  def initialize(app, opts) # :nodoc:
21
21
  @domain = opts[:domain]
22
- super(app, opts[:db])
22
+ endpoint_init(app, opts[:db])
23
23
  end
24
24
 
25
25
  def call(env) # :nodoc:
@@ -6,19 +6,14 @@ module Regurgitator::ServerSettings
6
6
  SETTINGS_LOOKUP = 'SELECT value FROM server_settings WHERE field = ? LIMIT 1'
7
7
  # :startdoc:
8
8
 
9
- def initialize(*args) # :nodoc:
10
- super
11
- init_zone_ivars
12
- end
13
-
14
- def init_zone_ivars
9
+ def server_settings_init
15
10
  @zone_cache_mtime = Time.at(0)
16
11
  @zone_cache = nil
17
12
  @zone_cache_lock = Mutex.new
18
13
  end
19
14
 
20
15
  def self.extended(obj)
21
- obj.init_zone_ivars
16
+ obj.server_settings_init
22
17
  end
23
18
 
24
19
  def refresh_zone(force = false) # :nodoc:
data/regurgitator.gemspec CHANGED
@@ -21,10 +21,11 @@ Gem::Specification.new do |s|
21
21
  s.rubyforge_project = %q{rainbows}
22
22
  s.test_files = Dir["test/test_*.rb"]
23
23
 
24
- s.add_dependency("rack", ["~> 1.2"])
25
- s.add_dependency("sequel", ["~> 3.23"])
26
- s.add_dependency("http_spew", ["~> 0.1"])
24
+ s.add_dependency("rack", ["~> 1.3"])
25
+ s.add_dependency("sequel", ["~> 3.29"])
26
+ s.add_dependency("http_spew", ["~> 0.4"])
27
+ s.add_dependency("rpatricia", ["~> 0.08"])
27
28
 
28
- s.add_development_dependency('wrongdoc', "~> 1.5")
29
+ s.add_development_dependency('wrongdoc', "~> 1.6")
29
30
  # s.licenses = %w(GPL2 GPL3) # accessor not compatible with older RubyGems
30
31
  end
data/test/test_local.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require "test/unit"
2
2
  require "regurgitator"
3
- require "tempfile"
3
+ require "tmpdir"
4
4
  require "fileutils"
5
5
 
6
6
  class TestLocal < Test::Unit::TestCase
@@ -16,10 +16,7 @@ class TestLocal < Test::Unit::TestCase
16
16
  @local_addrs = Regurgitator::Local.instance_variable_get(:@local_addrs)
17
17
  @local_addrs["127.0.0.1"] = true if @local_addrs.empty?
18
18
  @addr = @local_addrs.keys.first
19
- tmp = Tempfile.new('test_local')
20
- @tmpdir = tmp.path
21
- tmp.close!
22
- Dir.mkdir(@tmpdir)
19
+ @tmpdir = Dir.mktmpdir
23
20
  end
24
21
 
25
22
  def test_device_path_stat
@@ -74,5 +71,42 @@ class TestLocal < Test::Unit::TestCase
74
71
  File.open(path_a, "wb") { |fp| fp.write '.' }
75
72
  res = trylocal(env, [ [ a, b ] ])
76
73
  assert_kind_of Regurgitator::LocalFile, res
74
+ assert_equal 200, res.response[0]
75
+ end
76
+
77
+ def test_trylocal_range
78
+ port = 1233
79
+ env = { "REQUEST_METHOD" => "GET", "HTTP_RANGE" => "bytes=5-15" }
80
+ a = URI("http://#@addr:#{port}/dev10/0/004/689/0004689631.fid")
81
+ b = URI("http://#@addr:#{port + 6}/dev11/0/004/689/0004689631.fid")
82
+ assert_nil trylocal(env, [ [ a, b ] ])
83
+
84
+ path_a = "#@tmpdir#{a.path}"
85
+ FileUtils.mkdir_p(File.dirname(path_a))
86
+ Regurgitator::Local.register port, @tmpdir
87
+ File.open(path_a, "wb") { |fp| (0..15).each { |i| fp.write(i.to_s(16)) } }
88
+ res = trylocal(env, [ [ a, b ] ])
89
+ assert_kind_of Regurgitator::LocalFile, res
90
+ assert_equal(206, res.response[0])
91
+ body = ""
92
+ res.response[2].each { |x| body << x }
93
+ expect = (5..15).map { |x| x.to_s(16) }.join("")
94
+ assert_equal expect, body
95
+ end
96
+
97
+ def test_trylocal_bad_range
98
+ port = 1233
99
+ env = { "REQUEST_METHOD" => "GET", "HTTP_RANGE" => "bytes=515-999" }
100
+ a = URI("http://#@addr:#{port}/dev10/0/004/689/0004689631.fid")
101
+ b = URI("http://#@addr:#{port + 6}/dev11/0/004/689/0004689631.fid")
102
+ assert_nil trylocal(env, [ [ a, b ] ])
103
+
104
+ path_a = "#@tmpdir#{a.path}"
105
+ FileUtils.mkdir_p(File.dirname(path_a))
106
+ Regurgitator::Local.register port, @tmpdir
107
+ File.open(path_a, "wb") { |fp| (0..15).each { |i| fp.write(i.to_s(16)) } }
108
+ res = trylocal(env, [ [ a, b ] ])
109
+ assert_kind_of Regurgitator::LocalFile, res
110
+ assert_equal(416, res.response[0])
77
111
  end
78
112
  end
@@ -12,6 +12,7 @@ class TestServerSettings < Test::Unit::TestCase
12
12
  String :field, :size => 50, :null => false, :primary_key => true
13
13
  String :value, :size => 255
14
14
  end
15
+ server_settings_init
15
16
  end
16
17
 
17
18
  def test_zones
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: regurgitator
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 0
10
- version: 0.0.0
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Regurgitators
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-10 00:00:00 Z
18
+ date: 2011-11-11 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rack
@@ -25,11 +25,11 @@ dependencies:
25
25
  requirements:
26
26
  - - ~>
27
27
  - !ruby/object:Gem::Version
28
- hash: 11
28
+ hash: 9
29
29
  segments:
30
30
  - 1
31
- - 2
32
- version: "1.2"
31
+ - 3
32
+ version: "1.3"
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
35
  - !ruby/object:Gem::Dependency
@@ -40,11 +40,11 @@ dependencies:
40
40
  requirements:
41
41
  - - ~>
42
42
  - !ruby/object:Gem::Version
43
- hash: 41
43
+ hash: 61
44
44
  segments:
45
45
  - 3
46
- - 23
47
- version: "3.23"
46
+ - 29
47
+ version: "3.29"
48
48
  type: :runtime
49
49
  version_requirements: *id002
50
50
  - !ruby/object:Gem::Dependency
@@ -55,28 +55,43 @@ dependencies:
55
55
  requirements:
56
56
  - - ~>
57
57
  - !ruby/object:Gem::Version
58
- hash: 9
58
+ hash: 3
59
59
  segments:
60
60
  - 0
61
- - 1
62
- version: "0.1"
61
+ - 4
62
+ version: "0.4"
63
63
  type: :runtime
64
64
  version_requirements: *id003
65
65
  - !ruby/object:Gem::Dependency
66
- name: wrongdoc
66
+ name: rpatricia
67
67
  prerelease: false
68
68
  requirement: &id004 !ruby/object:Gem::Requirement
69
69
  none: false
70
70
  requirements:
71
71
  - - ~>
72
72
  - !ruby/object:Gem::Version
73
- hash: 5
73
+ hash: 27
74
+ segments:
75
+ - 0
76
+ - 8
77
+ version: "0.08"
78
+ type: :runtime
79
+ version_requirements: *id004
80
+ - !ruby/object:Gem::Dependency
81
+ name: wrongdoc
82
+ prerelease: false
83
+ requirement: &id005 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ~>
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
74
89
  segments:
75
90
  - 1
76
- - 5
77
- version: "1.5"
91
+ - 6
92
+ version: "1.6"
78
93
  type: :development
79
- version_requirements: *id004
94
+ version_requirements: *id005
80
95
  description: |-
81
96
  \Regurgitator is an GPL-licensed library and Rack middleware for
82
97
  serving files stored in MogileFS. It can be embedded inside
@@ -182,7 +197,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
182
197
  requirements: []
183
198
 
184
199
  rubyforge_project: rainbows
185
- rubygems_version: 1.8.1
200
+ rubygems_version: 1.8.5
186
201
  signing_key:
187
202
  specification_version: 3
188
203
  summary: read-only Rack endpoints for MogileFS