omgdav 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/.document +3 -0
  2. data/.gitignore +17 -0
  3. data/.manifest +53 -0
  4. data/.wrongdoc.yml +6 -0
  5. data/COPYING +661 -0
  6. data/ChangeLog +185 -0
  7. data/GIT-VERSION-FILE +1 -0
  8. data/GIT-VERSION-GEN +33 -0
  9. data/GNUmakefile +35 -0
  10. data/LATEST +1 -0
  11. data/NEWS +1 -0
  12. data/README +154 -0
  13. data/bin/omgdav-setup +4 -0
  14. data/bin/omgdav-sync +32 -0
  15. data/lib/omgdav/app.rb +70 -0
  16. data/lib/omgdav/copy.rb +100 -0
  17. data/lib/omgdav/copy_move.rb +54 -0
  18. data/lib/omgdav/db.rb +258 -0
  19. data/lib/omgdav/delete.rb +66 -0
  20. data/lib/omgdav/get.rb +35 -0
  21. data/lib/omgdav/http_get.rb +146 -0
  22. data/lib/omgdav/input_wrapper.rb +32 -0
  23. data/lib/omgdav/migrations/0001_initial.rb +45 -0
  24. data/lib/omgdav/migrations/0002_contenttype.rb +15 -0
  25. data/lib/omgdav/migrations/0003_synctmp.rb +14 -0
  26. data/lib/omgdav/mkcol.rb +28 -0
  27. data/lib/omgdav/move.rb +74 -0
  28. data/lib/omgdav/options.rb +21 -0
  29. data/lib/omgdav/propfind.rb +46 -0
  30. data/lib/omgdav/propfind_response.rb +150 -0
  31. data/lib/omgdav/proppatch.rb +116 -0
  32. data/lib/omgdav/put.rb +110 -0
  33. data/lib/omgdav/rack_util.rb +56 -0
  34. data/lib/omgdav/setup.rb +16 -0
  35. data/lib/omgdav/sync.rb +78 -0
  36. data/lib/omgdav/version.rb +2 -0
  37. data/lib/omgdav.rb +27 -0
  38. data/omgdav.gemspec +35 -0
  39. data/pkg.mk +175 -0
  40. data/setup.rb +1586 -0
  41. data/test/integration.rb +232 -0
  42. data/test/test_copy.rb +121 -0
  43. data/test/test_delete.rb +15 -0
  44. data/test/test_litmus.rb +61 -0
  45. data/test/test_move.rb +66 -0
  46. data/test/test_omgdav_app.rb +102 -0
  47. data/test/test_propfind.rb +30 -0
  48. data/test/test_proppatch.rb +156 -0
  49. data/test/test_put.rb +31 -0
  50. data/test/test_readonly.rb +22 -0
  51. data/test/test_sync.rb +49 -0
  52. data/test/test_urlmap.rb +59 -0
  53. data/test/test_worm.rb +26 -0
  54. metadata +342 -0
@@ -0,0 +1,156 @@
1
+ # -*- encoding: binary -*-
2
+ # Copyright (C) 2012, Eric Wong <normalperson@yhbt.net>
3
+ # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
4
+ require './test/integration'
5
+ class TestProppatch < MiniTest::Unit::TestCase
6
+ include TestMogileFSIntegration
7
+
8
+ def test_proppatch_live
9
+ assert_equal 201, req("MKCOL", "/prop")[0].to_i
10
+
11
+ t = Time.at(666)
12
+ xml = <<-EOF
13
+ <?xml version="1.0" encoding="utf-8"?>
14
+ <D:propertyupdate xmlns:D="DAV:">
15
+ <D:set>
16
+ <D:prop>
17
+ <getlastmodified xmlns="DAV:">#{t.httpdate}</getlastmodified>
18
+ </D:prop>
19
+ </D:set>
20
+ </D:propertyupdate>
21
+ EOF
22
+ opts = {
23
+ input: StringIO.new(xml.strip!)
24
+ }
25
+
26
+ assert_equal 200, req("PROPPATCH", "/prop", opts)[0].to_i
27
+ assert_equal 666, @db[:paths][name: "prop"][:mtime]
28
+ end
29
+
30
+ def test_getcontenttype
31
+ path = "//D:multistatus/D:response/D:propstat/D:prop/D:getcontenttype"
32
+ assert_equal 201, req("PUT", "/type")[0].to_i
33
+ _, _, body = req("PROPFIND", "/type", "HTTP_DEPTH" => '0')
34
+ t = Nokogiri::XML(body).search(path)
35
+ assert_equal "application/octet-stream", t.text
36
+
37
+ xml = <<-EOF
38
+ <?xml version="1.0" encoding="utf-8"?>
39
+ <D:propertyupdate xmlns:D="DAV:">
40
+ <D:set>
41
+ <D:prop>
42
+ <getcontenttype xmlns="DAV:">audio/flac</getcontenttype>
43
+ </D:prop>
44
+ </D:set>
45
+ </D:propertyupdate>
46
+ EOF
47
+ opts = {
48
+ input: StringIO.new(xml.strip!)
49
+ }
50
+
51
+ assert_equal 200, req("PROPPATCH", "/type", opts)[0].to_i
52
+ _, _, body = req("PROPFIND", "/type", "HTTP_DEPTH" => '0')
53
+ t = Nokogiri::XML(body).search(path)
54
+ assert_equal "audio/flac", t.text
55
+
56
+ xml = <<-EOF
57
+ <?xml version="1.0" encoding="utf-8" ?>
58
+ <D:propertyupdate xmlns:D="DAV:"
59
+ xmlns:Z="http://ns.example.com/standards/z39.50/">
60
+ <D:remove>
61
+ <D:prop><D:getcontenttype/></D:prop>
62
+ </D:remove>
63
+ </D:propertyupdate>
64
+ EOF
65
+ opts = {
66
+ input: StringIO.new(xml.strip!)
67
+ }
68
+ assert_equal 200, req("PROPPATCH", "/type", opts)[0].to_i
69
+ _, _, body = req("PROPFIND", "/type", "HTTP_DEPTH" => '0')
70
+ t = Nokogiri::XML(body).search(path)
71
+ assert_equal "application/octet-stream", t.text
72
+
73
+ opts = {
74
+ "HTTP_DESTINATION" => "http://example.com/type.txt",
75
+ "HTTP_HOST" => "example.com",
76
+ }
77
+ assert_equal 201, req("MOVE", "/type", opts)[0].to_i
78
+ _, _, body = req("PROPFIND", "/type.txt", "HTTP_DEPTH" => '0')
79
+ t = Nokogiri::XML(body).search(path)
80
+ assert_equal "text/plain", t.text
81
+
82
+ # try something invalid
83
+ [
84
+ "audio flac",
85
+ "foo/bar adlkj",
86
+ "foo/bar paramet()=ff"
87
+ ].each do |bad|
88
+ xml = <<-EOF
89
+ <?xml version="1.0" encoding="utf-8"?>
90
+ <D:propertyupdate xmlns:D="DAV:">
91
+ <D:set>
92
+ <D:prop>
93
+ <getcontenttype xmlns="DAV:">#{bad}</getcontenttype>
94
+ </D:prop>
95
+ </D:set>
96
+ </D:propertyupdate>
97
+ EOF
98
+ opts = { input: StringIO.new(xml.strip!) }
99
+ assert_equal 400, req("PROPPATCH", "/type.txt", opts)[0].to_i, bad
100
+ assert_nil @db[:paths][name: "type.txt"][:contenttype]
101
+ end
102
+
103
+ xml = <<-EOF
104
+ <?xml version="1.0" encoding="utf-8"?>
105
+ <D:propertyupdate xmlns:D="DAV:">
106
+ <D:set>
107
+ <D:prop>
108
+ <getcontenttype xmlns="DAV:">teXt/plain; chArset="ASCII"</getcontenttype>
109
+ </D:prop>
110
+ </D:set>
111
+ </D:propertyupdate>
112
+ EOF
113
+ opts = { input: StringIO.new(xml.strip!) }
114
+ assert_equal 200, req("PROPPATCH", "/type.txt", opts)[0].to_i
115
+ i = @db[:paths][name: "type.txt"][:contenttype]
116
+ assert_kind_of Integer, i
117
+ t = @db[:prop_mappings][id: i][:value]
118
+ assert_equal 'text/plain; charset="ASCII"', t
119
+ refute_equal i, @db[:prop_mappings][value: 'audio/flac'][:id]
120
+ end
121
+
122
+ def test_proppatch_dead
123
+ assert_equal 201, req("MKCOL", "/prop")[0].to_i
124
+
125
+ xml = <<-EOF
126
+ <?xml version="1.0" encoding="utf-8" ?>
127
+ <D:propertyupdate xmlns:D="DAV:"
128
+ xmlns:Z="http://ns.example.com/standards/z39.50/">
129
+ <D:set>
130
+ <D:prop>
131
+ <Z:Authors>
132
+ <Z:Author>Jim Whitehead</Z:Author>
133
+ <Z:Author>Roy Fielding</Z:Author>
134
+ </Z:Authors>
135
+ </D:prop>
136
+ </D:set>
137
+ <D:remove>
138
+ <D:prop><Z:Copyright-Owner/></D:prop>
139
+ </D:remove>
140
+ </D:propertyupdate>
141
+ EOF
142
+ opts = {
143
+ input: StringIO.new(xml.strip!)
144
+ }
145
+
146
+ assert_equal 200, req("PROPPATCH", "/prop", opts)[0].to_i
147
+ prop = @db[:paths][name: "prop"]
148
+ props = @app.dead_props_get(prop)
149
+ ns_prop = props["http://ns.example.com/standards/z39.50/"]
150
+ assert_instance_of Hash, ns_prop
151
+ authors = ns_prop["Authors"].strip
152
+ expect = "<Author>Jim Whitehead</Author>\n" \
153
+ " <Author>Roy Fielding</Author>"
154
+ assert_equal expect, authors
155
+ end
156
+ end
data/test/test_put.rb ADDED
@@ -0,0 +1,31 @@
1
+ # -*- encoding: binary -*-
2
+ # Copyright (C) 2012, Eric Wong <normalperson@yhbt.net>
3
+ # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
4
+ require './test/integration'
5
+ class TestPut < MiniTest::Unit::TestCase
6
+ include TestMogileFSIntegration
7
+
8
+ def test_put_overwrite
9
+ resp = @req.put("/hello", input: StringIO.new("HELLO"))
10
+ assert_equal 201, resp.status.to_i
11
+ before = @db[:paths].to_a[0]
12
+
13
+ status, headers, body = req("GET", "/hello")
14
+ assert_equal 200, status.to_i
15
+ assert_equal "5", headers["Content-Length"]
16
+ assert_equal "HELLO", body_string(body)
17
+
18
+ resp = @req.put("/hello", input: StringIO.new("GOODBYE"))
19
+ assert_equal 204, resp.status.to_i
20
+ after = @db[:paths].to_a[0]
21
+
22
+ status, headers, body = req("GET", "/hello")
23
+ assert_equal 200, status.to_i
24
+ assert_equal "7", headers["Content-Length"]
25
+ assert_equal "GOODBYE", body_string(body)
26
+
27
+ [ :parent_id, :id, :domain_id, :name ].each do |field|
28
+ assert_equal before[field], after[field]
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: binary -*-
2
+ # Copyright (C) 2012, Eric Wong <normalperson@yhbt.net>
3
+ # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
4
+ require './test/integration'
5
+ class Test_ReadOnly < MiniTest::Unit::TestCase
6
+ include TestMogileFSIntegration
7
+
8
+ def test_readonly
9
+ resp = @req.put("/foo", input: StringIO.new("HELLO"))
10
+ assert_equal 201, resp.status.to_i
11
+
12
+ @app = OMGDAV::App.new(@db, @mogc, methods: :ro)
13
+ @req = Rack::MockRequest.new(@app)
14
+ resp = @req.put("/foo", input: StringIO.new("GOODBYE"))
15
+ assert_equal 405, resp.status.to_i
16
+ status, _, body = req("GET", "/foo")
17
+ assert_equal 200, status.to_i
18
+ assert_equal "HELLO", body_string(body)
19
+
20
+ assert_equal 405, req("DELETE", "/foo")[0].to_i
21
+ end
22
+ end
data/test/test_sync.rb ADDED
@@ -0,0 +1,49 @@
1
+ # Copyright (C) 2012, Eric Wong <normalperson@yhbt.net>
2
+ # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
3
+ require "./test/integration"
4
+ require "omgdav/sync"
5
+
6
+ class TestSync < MiniTest::Unit::TestCase
7
+ include TestMogileFSIntegration
8
+
9
+ def test_sync
10
+ nr = 0
11
+ (5..11).each do |i|
12
+ (995..1005).each do |j|
13
+ @mogc.store_content("#{i}/#{j}", "default", "#{i}-#{j}")
14
+ @mogc.store_content("#{j}/#{i}", "default", "#{j}-#{i}")
15
+ nr += 2
16
+ end
17
+ end
18
+ imp = OMGDAV::Sync.new(@db, @mogc)
19
+ imp.sync
20
+ paths = @db[:paths].where { self.>(:parent_id, 0) }
21
+ assert_equal nr, paths.where(collection: false).count
22
+ assert_equal 18, paths.where(collection: true).count
23
+ keys, _ = @mogc.list_keys
24
+ cache = {}
25
+ pkeys = []
26
+ paths.where(collection: false).each do |node|
27
+ pkeys << @app.node_to_key(node, cache)
28
+ end
29
+ assert_equal keys.sort, pkeys.sort
30
+
31
+ # ensure MogileFS-only deletions are synced
32
+ first = keys.shift
33
+ @mogc.delete(first)
34
+ imp.sync
35
+
36
+ pkeys.clear
37
+ cache.clear
38
+ paths.where(collection: false).each do |node|
39
+ pkeys << @app.node_to_key(node, cache)
40
+ end
41
+ assert_equal(keys.size, pkeys.size)
42
+ refute pkeys.include?(first)
43
+
44
+ # nuke it all!
45
+ keys.each { |key| @mogc.delete(key) }
46
+ imp.sync
47
+ assert_equal 0, @db[:paths].where(collection: false).count
48
+ end
49
+ end
@@ -0,0 +1,59 @@
1
+ # -*- encoding: binary -*-
2
+ # Copyright (C) 2012, Eric Wong <normalperson@yhbt.net>
3
+ # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
4
+ require './test/integration'
5
+ require 'rack/builder'
6
+ require 'rack/lobster'
7
+
8
+ # ensure everything works when we're using Rack::URLMap with builder
9
+ class TestUrlmap < MiniTest::Unit::TestCase
10
+ include TestMogileFSIntegration
11
+
12
+ def test_url_map
13
+ old_app = @app
14
+ @app = Rack::Builder.new do
15
+ map "/test" do
16
+ run old_app
17
+ end
18
+ map "http://example.com/test" do
19
+ run old_app
20
+ end
21
+ map "/bogus" do
22
+ run Rack::Lobster.new
23
+ end
24
+ end.to_app
25
+
26
+ assert_equal 201, req("PUT", "/test/foo", input: StringIO.new("H"))[0].to_i
27
+
28
+ assert_equal "foo", @db[:paths].where { self.~(parent_id: 0) }.first[:name]
29
+ status, headers, body = req("PROPFIND", "/test", "HTTP_DEPTH" => "1")
30
+ xml = Nokogiri.XML(body)
31
+ hrefs = xml.search("//D:href").to_a.map { |x| x.text }
32
+ assert_equal 2, hrefs.size
33
+ assert hrefs.include?("/test/"), hrefs.inspect
34
+ assert hrefs.include?("/test/foo"), hrefs.inspect
35
+
36
+ assert_equal 200, req("HEAD", "/test/foo")[0].to_i
37
+
38
+ opts = {
39
+ "HTTP_DESTINATION" => "http://example.com/test/bar",
40
+ "HTTP_HOST" => "example.com",
41
+ }
42
+ assert_equal 201, req("MOVE", "/test/foo", opts)[0].to_i
43
+ opts["HTTP_DESTINATION"] = "http://example.com/bar"
44
+ assert_equal 502, req("MOVE", "/test/bar", opts)[0].to_i
45
+
46
+ opts["HTTP_DESTINATION"] = "http://example.com/test/foo"
47
+ assert_equal 201, req("COPY", "/test/bar", opts)[0].to_i
48
+
49
+ assert_equal 201, req("MKCOL", "/test/col")[0].to_i
50
+ opts["HTTP_DESTINATION"] = "http://example.com/test/col/foo"
51
+ assert_equal 201, req("COPY", "/test/bar", opts)[0].to_i
52
+
53
+ opts["HTTP_DESTINATION"] = "http://example.com/zz"
54
+ assert_equal 502, req("MOVE", "/test/col/", opts)[0].to_i
55
+
56
+ opts["HTTP_DESTINATION"] = "http://example.com/test/COL"
57
+ assert_equal 201, req("MOVE", "/test/col/", opts)[0].to_i
58
+ end
59
+ end
data/test/test_worm.rb ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: binary -*-
2
+ # Copyright (C) 2012, Eric Wong <normalperson@yhbt.net>
3
+ # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
4
+ require './test/integration'
5
+ class TestWorm < MiniTest::Unit::TestCase
6
+ include TestMogileFSIntegration
7
+
8
+ def test_worm
9
+ resp = @req.put("/foo", input: StringIO.new("HELLO"))
10
+ assert_equal 201, resp.status.to_i
11
+
12
+ @app = OMGDAV::App.new(@db, @mogc, methods: :worm)
13
+ @req = Rack::MockRequest.new(@app)
14
+ resp = @req.put("/foo", input: StringIO.new("GOODBYE"))
15
+ assert_equal 409, resp.status.to_i
16
+
17
+ resp = @req.put("/bar", input: StringIO.new("GOODBYE"))
18
+ assert_equal 201, resp.status.to_i
19
+
20
+ status, _, body = req("GET", "/foo")
21
+ assert_equal 200, status.to_i
22
+ assert_equal "HELLO", body_string(body)
23
+
24
+ assert_equal 405, req("DELETE", "/foo")[0].to_i
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,342 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: !binary |-
3
+ b21nZGF2
4
+ version: !ruby/object:Gem::Version
5
+ version: 0.0.0
6
+ prerelease:
7
+ platform: ruby
8
+ authors:
9
+ - !binary |-
10
+ T01HREFWIGhhY2tlcnM=
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2012-11-15 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: !binary |-
18
+ cmFjaw==
19
+ requirement: !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - !binary |-
23
+ fj4=
24
+ - !ruby/object:Gem::Version
25
+ version: !binary |-
26
+ MS40
27
+ type: :runtime
28
+ prerelease: false
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - !binary |-
33
+ fj4=
34
+ - !ruby/object:Gem::Version
35
+ version: !binary |-
36
+ MS40
37
+ - !ruby/object:Gem::Dependency
38
+ name: !binary |-
39
+ a2dpbw==
40
+ requirement: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - !binary |-
44
+ fj4=
45
+ - !ruby/object:Gem::Version
46
+ version: !binary |-
47
+ Mi43
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - !binary |-
54
+ fj4=
55
+ - !ruby/object:Gem::Version
56
+ version: !binary |-
57
+ Mi43
58
+ - !ruby/object:Gem::Dependency
59
+ name: !binary |-
60
+ a2Nhcg==
61
+ requirement: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - !binary |-
65
+ fj4=
66
+ - !ruby/object:Gem::Version
67
+ version: !binary |-
68
+ MC40
69
+ type: :runtime
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - !binary |-
75
+ fj4=
76
+ - !ruby/object:Gem::Version
77
+ version: !binary |-
78
+ MC40
79
+ - !ruby/object:Gem::Dependency
80
+ name: !binary |-
81
+ ZmFzdF94cw==
82
+ requirement: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - !binary |-
86
+ fj4=
87
+ - !ruby/object:Gem::Version
88
+ version: !binary |-
89
+ MC44
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - !binary |-
96
+ fj4=
97
+ - !ruby/object:Gem::Version
98
+ version: !binary |-
99
+ MC44
100
+ - !ruby/object:Gem::Dependency
101
+ name: !binary |-
102
+ bW9naWxlZnMtY2xpZW50
103
+ requirement: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - !binary |-
107
+ fj4=
108
+ - !ruby/object:Gem::Version
109
+ version: !binary |-
110
+ My40
111
+ type: :runtime
112
+ prerelease: false
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - !binary |-
117
+ fj4=
118
+ - !ruby/object:Gem::Version
119
+ version: !binary |-
120
+ My40
121
+ - !ruby/object:Gem::Dependency
122
+ name: !binary |-
123
+ bm9rb2dpcmk=
124
+ requirement: !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - !binary |-
128
+ fj4=
129
+ - !ruby/object:Gem::Version
130
+ version: !binary |-
131
+ MS41
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - !binary |-
138
+ fj4=
139
+ - !ruby/object:Gem::Version
140
+ version: !binary |-
141
+ MS41
142
+ - !ruby/object:Gem::Dependency
143
+ name: !binary |-
144
+ c2VxdWVs
145
+ requirement: !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - !binary |-
149
+ fj4=
150
+ - !ruby/object:Gem::Version
151
+ version: !binary |-
152
+ My40MQ==
153
+ - - !binary |-
154
+ Pj0=
155
+ - !ruby/object:Gem::Version
156
+ version: !binary |-
157
+ My40MS4w
158
+ type: :runtime
159
+ prerelease: false
160
+ version_requirements: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - !binary |-
164
+ fj4=
165
+ - !ruby/object:Gem::Version
166
+ version: !binary |-
167
+ My40MQ==
168
+ - - !binary |-
169
+ Pj0=
170
+ - !ruby/object:Gem::Version
171
+ version: !binary |-
172
+ My40MS4w
173
+ - !ruby/object:Gem::Dependency
174
+ name: !binary |-
175
+ dW5pY29ybg==
176
+ requirement: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - !binary |-
180
+ fj4=
181
+ - !ruby/object:Gem::Version
182
+ version: !binary |-
183
+ NC40LjA=
184
+ type: :development
185
+ prerelease: false
186
+ version_requirements: !ruby/object:Gem::Requirement
187
+ none: false
188
+ requirements:
189
+ - - !binary |-
190
+ fj4=
191
+ - !ruby/object:Gem::Version
192
+ version: !binary |-
193
+ NC40LjA=
194
+ - !ruby/object:Gem::Dependency
195
+ name: !binary |-
196
+ d3Jvbmdkb2M=
197
+ requirement: !ruby/object:Gem::Requirement
198
+ none: false
199
+ requirements:
200
+ - - !binary |-
201
+ fj4=
202
+ - !ruby/object:Gem::Version
203
+ version: !binary |-
204
+ MS42LjE=
205
+ type: :development
206
+ prerelease: false
207
+ version_requirements: !ruby/object:Gem::Requirement
208
+ none: false
209
+ requirements:
210
+ - - !binary |-
211
+ fj4=
212
+ - !ruby/object:Gem::Version
213
+ version: !binary |-
214
+ MS42LjE=
215
+ description: ! 'omgdav exposes an existing MogileFS domain over WebDAV. There is
216
+
217
+ absolutely no commitment or modification needed to your existing
218
+
219
+ MogileFS installation to try omgdav in read-only mode.'
220
+ email: !binary |-
221
+ bm9ybWFscGVyc29uQHloYnQubmV0
222
+ executables:
223
+ - !binary |-
224
+ b21nZGF2LXNldHVw
225
+ - !binary |-
226
+ b21nZGF2LXN5bmM=
227
+ extensions: []
228
+ extra_rdoc_files:
229
+ - ChangeLog
230
+ - NEWS
231
+ - README
232
+ files:
233
+ - .document
234
+ - .gitignore
235
+ - .manifest
236
+ - .wrongdoc.yml
237
+ - COPYING
238
+ - ChangeLog
239
+ - GIT-VERSION-FILE
240
+ - GIT-VERSION-GEN
241
+ - GNUmakefile
242
+ - LATEST
243
+ - NEWS
244
+ - README
245
+ - bin/omgdav-setup
246
+ - bin/omgdav-sync
247
+ - lib/omgdav.rb
248
+ - lib/omgdav/app.rb
249
+ - lib/omgdav/copy.rb
250
+ - lib/omgdav/copy_move.rb
251
+ - lib/omgdav/db.rb
252
+ - lib/omgdav/delete.rb
253
+ - lib/omgdav/get.rb
254
+ - lib/omgdav/http_get.rb
255
+ - lib/omgdav/input_wrapper.rb
256
+ - lib/omgdav/migrations/0001_initial.rb
257
+ - lib/omgdav/migrations/0002_contenttype.rb
258
+ - lib/omgdav/migrations/0003_synctmp.rb
259
+ - lib/omgdav/mkcol.rb
260
+ - lib/omgdav/move.rb
261
+ - lib/omgdav/options.rb
262
+ - lib/omgdav/propfind.rb
263
+ - lib/omgdav/propfind_response.rb
264
+ - lib/omgdav/proppatch.rb
265
+ - lib/omgdav/put.rb
266
+ - lib/omgdav/rack_util.rb
267
+ - lib/omgdav/setup.rb
268
+ - lib/omgdav/sync.rb
269
+ - lib/omgdav/version.rb
270
+ - omgdav.gemspec
271
+ - pkg.mk
272
+ - setup.rb
273
+ - test/integration.rb
274
+ - test/test_copy.rb
275
+ - test/test_delete.rb
276
+ - test/test_litmus.rb
277
+ - test/test_move.rb
278
+ - test/test_omgdav_app.rb
279
+ - test/test_propfind.rb
280
+ - test/test_proppatch.rb
281
+ - test/test_put.rb
282
+ - test/test_readonly.rb
283
+ - test/test_sync.rb
284
+ - test/test_urlmap.rb
285
+ - test/test_worm.rb
286
+ homepage: http://bogomips.org/omgdav/README
287
+ licenses:
288
+ - !binary |-
289
+ QUdQTHYzKw==
290
+ post_install_message:
291
+ rdoc_options:
292
+ - -t
293
+ - omgdav - Rack app for bridging WebDAV and MogileFS
294
+ - -W
295
+ - http://bogomips.org/omgdav.git/tree/%s
296
+ require_paths:
297
+ - lib
298
+ required_ruby_version: !ruby/object:Gem::Requirement
299
+ none: false
300
+ requirements:
301
+ - - !binary |-
302
+ fj4=
303
+ - !ruby/object:Gem::Version
304
+ version: !binary |-
305
+ MS45
306
+ required_rubygems_version: !ruby/object:Gem::Requirement
307
+ none: false
308
+ requirements:
309
+ - - ! '>='
310
+ - !ruby/object:Gem::Version
311
+ version: '0'
312
+ requirements: []
313
+ rubyforge_project:
314
+ rubygems_version: 1.8.23
315
+ signing_key:
316
+ specification_version: 3
317
+ summary: Rack app for bridging WebDAV and MogileFS
318
+ test_files:
319
+ - !binary |-
320
+ dGVzdC90ZXN0X2xpdG11cy5yYg==
321
+ - !binary |-
322
+ dGVzdC90ZXN0X29tZ2Rhdl9hcHAucmI=
323
+ - !binary |-
324
+ dGVzdC90ZXN0X3N5bmMucmI=
325
+ - !binary |-
326
+ dGVzdC90ZXN0X21vdmUucmI=
327
+ - !binary |-
328
+ dGVzdC90ZXN0X3dvcm0ucmI=
329
+ - !binary |-
330
+ dGVzdC90ZXN0X3B1dC5yYg==
331
+ - !binary |-
332
+ dGVzdC90ZXN0X3Byb3BmaW5kLnJi
333
+ - !binary |-
334
+ dGVzdC90ZXN0X3VybG1hcC5yYg==
335
+ - !binary |-
336
+ dGVzdC90ZXN0X2RlbGV0ZS5yYg==
337
+ - !binary |-
338
+ dGVzdC90ZXN0X3JlYWRvbmx5LnJi
339
+ - !binary |-
340
+ dGVzdC90ZXN0X3Byb3BwYXRjaC5yYg==
341
+ - !binary |-
342
+ dGVzdC90ZXN0X2NvcHkucmI=