railsdav 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +16 -8
- data/lib/railsdav/renderer/response_collector.rb +5 -1
- data/lib/railsdav/renderer/response_type_selector.rb +2 -1
- data/lib/railsdav/renderer.rb +72 -15
- data/lib/railsdav/routing_extensions.rb +12 -30
- metadata +13 -15
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4fb6b8fa60267d9d8e9b95e30e13241660ab4411
|
4
|
+
data.tar.gz: ce5b83d84a637aae35036dd3e37e46be1a2371ce
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: af43e93abe5e6244f74f151ab4f0ea4e270d2298dcab9ce63588a9fbd124cd0bf5cfac7c2b9d5c5fd692402fbc9ca82777237e62c7565ff51ffc8b70bca34d28
|
7
|
+
data.tar.gz: 0f0f09fd4cb561d8f5c8cff56cb1a5348b25948a0321fdad4322d8bfd92eeeb0e37160243e555bb7ee70e4920dce1934b5189fd64b3aafdfee6f4c6496dba450
|
data/README.md
CHANGED
@@ -1,27 +1,34 @@
|
|
1
1
|
# RailsDAV
|
2
2
|
|
3
|
-
Make your Rails
|
3
|
+
Make your Rails 4 resources accessible via WebDAV.
|
4
4
|
|
5
|
-
|
5
|
+
This gem provides basic Rails 3 extensions for making your business
|
6
|
+
resources accessible via WebDAV. This gem does by no means by no means
|
7
|
+
implement the full WebDAV semantics, but it suffices to access your
|
8
|
+
app with client(-libs) such as Konqueror, cadaver, davfs2 or NetDrive.
|
6
9
|
|
7
10
|
## Compatibility
|
8
11
|
|
9
|
-
Definitely works with Rails 3.0.9 and 3.2.13, but should also work
|
10
|
-
This is due to some hacking done "under the
|
12
|
+
Definitely works with Rails 3.0.9 and 3.2.13, but should also work
|
13
|
+
with versions in between. This is due to some hacking done "under the
|
14
|
+
hood" in the Rails routing implementation as well as a simple method
|
15
|
+
override in ActionController.
|
11
16
|
|
12
|
-
|
17
|
+
If you encounter any problems with other Rails versions, please feel
|
18
|
+
free to report an issue or send me a pull request on github.
|
13
19
|
|
14
20
|
## Installation
|
15
21
|
|
16
|
-
|
22
|
+
Ensure that your project has the
|
23
|
+
[Rails ActionPack XML Params Parser gem](https://github.com/rails/actionpack-xml_parser)
|
24
|
+
installed, and then just add the following to your Gemfile:
|
17
25
|
|
18
26
|
gem 'railsdav', :git => 'https://github.com/wvk/railsdav.git'
|
19
27
|
|
20
|
-
and then run
|
28
|
+
and then run:
|
21
29
|
|
22
30
|
bundle install
|
23
31
|
|
24
|
-
|
25
32
|
## Usage
|
26
33
|
|
27
34
|
TODO: Context
|
@@ -175,6 +182,7 @@ is_webdav_request? checks whether an Incoming request is issued by a WebDAV clie
|
|
175
182
|
|
176
183
|
## Changelog
|
177
184
|
|
185
|
+
* 0.0.8: Merge Contributions from naserca, orospakr, and rutgerg
|
178
186
|
* 0.0.7: Fix metadata class attribute inheritance problem
|
179
187
|
* 0.0.6: Fix update_all for Rails 3.2
|
180
188
|
* 0.0.5: Rails 3.2.x compatibility, add encoding hints, fix ResourceDescriptor load error
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
require "uri"
|
4
|
+
|
3
5
|
module Railsdav
|
4
6
|
class Renderer
|
5
7
|
class ResponseCollector
|
@@ -14,7 +16,9 @@ module Railsdav
|
|
14
16
|
end
|
15
17
|
|
16
18
|
def resource
|
17
|
-
|
19
|
+
|
20
|
+
request_path = URI(@controller.request.url).path
|
21
|
+
@resource ||= Renderer::ResourceDescriptor.new(request_path, @selector.resource_options)
|
18
22
|
end
|
19
23
|
|
20
24
|
# responds to calls like html, xml, json by ignoring them
|
@@ -31,7 +31,8 @@ module Railsdav
|
|
31
31
|
|
32
32
|
options = subresources.extract_options!
|
33
33
|
subresources.each do |resource_url|
|
34
|
-
|
34
|
+
relative_resource_url = resource_url.sub %r(^#{ActionController::Base.relative_url_root}), '' # HACK
|
35
|
+
route = Rails.application.routes.recognize_path(relative_resource_url)
|
35
36
|
|
36
37
|
if meta = Renderer.webdav_metadata_for_url(route)
|
37
38
|
# show the resource as a collection unless disabled
|
data/lib/railsdav/renderer.rb
CHANGED
@@ -29,7 +29,9 @@ module Railsdav
|
|
29
29
|
def initialize(controller)
|
30
30
|
@controller = controller
|
31
31
|
@request = controller.request
|
32
|
-
@depth = (@request.headers['Depth'].to_i > 0) ? 1 : 0 # depth "infinite" is not yet supported
|
32
|
+
# @depth = (@request.headers['Depth'].to_i > 0) ? 1 : 0 # depth "infinite" is not yet supported
|
33
|
+
@depth = (@request.headers['Depth'].to_i)
|
34
|
+
Rails.logger.debug "Depth:\n#{@request.headers['Depth']}"
|
33
35
|
end
|
34
36
|
|
35
37
|
# Render the requested response_type.
|
@@ -60,7 +62,7 @@ module Railsdav
|
|
60
62
|
def render
|
61
63
|
@dav = Builder::XmlMarkup.new :indent => 2
|
62
64
|
@dav.instruct!
|
63
|
-
@dav.multistatus :
|
65
|
+
@dav.tag!("D:multistatus", "xmlns:D" => 'DAV:') do
|
64
66
|
yield @dav
|
65
67
|
end
|
66
68
|
@dav.target!
|
@@ -91,7 +93,15 @@ module Railsdav
|
|
91
93
|
def status_for(status)
|
92
94
|
code = Rack::Utils.status_code(status || :ok)
|
93
95
|
status = "HTTP/1.1 #{code} #{Rack::Utils::HTTP_STATUS_CODES[code]}"
|
94
|
-
@dav.status status
|
96
|
+
@dav.tag! "D:status", status
|
97
|
+
end
|
98
|
+
|
99
|
+
# Allows you to `render :webdav => :not_found` and get a 404
|
100
|
+
# status properly embedded inside multi-status
|
101
|
+
def not_found(options = {})
|
102
|
+
render do |dav|
|
103
|
+
status_for 404
|
104
|
+
end
|
95
105
|
end
|
96
106
|
|
97
107
|
# Render a WebDAV multistatus response with a "response" element per resource
|
@@ -136,41 +146,88 @@ module Railsdav
|
|
136
146
|
updated_at = Time.now
|
137
147
|
end
|
138
148
|
|
149
|
+
# note: all of these are assumed to be from the DAV:
|
150
|
+
# namespace!
|
139
151
|
response_hash = {
|
140
152
|
:quota_used_bytes => 0,
|
141
153
|
:quota_available_bytes => 10.gigabytes,
|
142
|
-
:creationdate => updated_at.
|
154
|
+
:creationdate => updated_at.iso8601,
|
143
155
|
:getlastmodified => updated_at.rfc2822,
|
144
156
|
:getcontentlength => hash[:size],
|
145
157
|
:getcontenttype => hash[:format].to_s
|
146
158
|
}
|
147
159
|
|
148
160
|
if resource.collection?
|
149
|
-
response_hash[:resourcetype] = proc { @dav.tag! :collection } # must be block to render <collection></collection> instead of "collection"
|
161
|
+
response_hash[:resourcetype] = proc { @dav.tag! "D:collection" } # must be block to render <collection></collection> instead of "collection"
|
150
162
|
response_hash[:getcontenttype] = nil
|
151
163
|
end
|
152
164
|
|
153
165
|
requested_properties ||= response_hash.keys
|
154
166
|
|
167
|
+
# as a workaround for another bug in Flycode's WebDAV module,
|
168
|
+
# which expects (because of how it does element name matching)
|
169
|
+
# that the properties are always returned with a specified
|
170
|
+
# namespace prefix. Now, the original Railsdav makes a
|
171
|
+
# slightly careless assumption of its own; it just directly
|
172
|
+
# matches element names in its fixed list, counting on (and
|
173
|
+
# there are none so far) collisions between property names
|
174
|
+
# from various name spaces. As such, it just assumes that if
|
175
|
+
# the property name is discrimated by a namespace, the client
|
176
|
+
# has only done so by putting a non-prefixed `xmlns` attribute
|
177
|
+
# on the propfind properties (ie., it did not try to use a
|
178
|
+
# prefix itself). Railsdav really should track and match
|
179
|
+
# properties by both name *and* namespace, in order to be
|
180
|
+
# properly compliant.
|
181
|
+
|
182
|
+
# So, back to the Flycode WebDAV bug: we work around this here
|
183
|
+
# by collecting all of the requested properties, gathering the
|
184
|
+
# namespaces from them, and defining them *all* as prefixes.
|
185
|
+
|
186
|
+
# all of our built-in properties are in the DAV namespace
|
187
|
+
# anyway:
|
188
|
+
gathered_namespaces = {"xmlns:lp0" => "DAV:"}
|
189
|
+
@namespace_counter ||= 1
|
190
|
+
|
191
|
+
namespaced_requested_properties = {}
|
192
|
+
|
193
|
+
requested_properties.each do |prop_name, opts|
|
194
|
+
if prop_name.to_s.include?(":")
|
195
|
+
# see first paragraph of big comment above
|
196
|
+
Rails.logger.warn("DAV propfind prop request contains a namespace prefix; we do NOT handle these properly yet!")
|
197
|
+
end
|
198
|
+
if (!opts.nil?) && opts["xmlns"]
|
199
|
+
gathered_namespaces["xmlns:lp#{@namespace_counter}"] = opts["xmlns"]
|
200
|
+
opts.delete("xmlns")
|
201
|
+
namespaced_requested_properties["lp#{@namespace_counter}:#{prop_name}"] = opts
|
202
|
+
@namespace_counter +=1
|
203
|
+
else
|
204
|
+
# just copy it through; however, we'll assume it's in the
|
205
|
+
# DAV namespace (which we hardcoded to the `lp0` prefix).
|
206
|
+
namespaced_requested_properties["lp0:#{prop_name}"] = opts
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
155
210
|
response_for(resource.url) do |dav|
|
156
|
-
dav.propstat do
|
211
|
+
dav.tag! "D:propstat", gathered_namespaces do
|
157
212
|
status_for hash[:status]
|
158
|
-
dav.prop do
|
159
|
-
|
213
|
+
dav.tag! "D:prop" do
|
214
|
+
namespaced_requested_properties.each do |both_prop_name, opts|
|
215
|
+
prop_space_and_name_pair = both_prop_name.split(":")
|
216
|
+
prop_name = prop_space_and_name_pair[1] || prop_space_and_name_pair[0]
|
160
217
|
if prop_val = response_hash[prop_name.to_sym]
|
161
218
|
if prop_val.respond_to? :call
|
162
219
|
if opts
|
163
|
-
dav.tag!
|
220
|
+
dav.tag! both_prop_name, opts, &prop_val
|
164
221
|
else
|
165
|
-
dav.tag!
|
222
|
+
dav.tag! both_prop_name, &prop_val
|
166
223
|
end
|
167
224
|
else
|
168
|
-
dav.tag!
|
225
|
+
dav.tag! both_prop_name, prop_val, opts
|
169
226
|
end
|
170
227
|
elsif opts
|
171
|
-
dav.tag!
|
228
|
+
dav.tag! both_prop_name, opts
|
172
229
|
else
|
173
|
-
dav.tag!
|
230
|
+
dav.tag! both_prop_name
|
174
231
|
end
|
175
232
|
end # requested_properties.each
|
176
233
|
end # dav.prop
|
@@ -180,8 +237,8 @@ module Railsdav
|
|
180
237
|
end # def propstat_for
|
181
238
|
|
182
239
|
def response_for(href)
|
183
|
-
@dav.response do
|
184
|
-
@dav.href href
|
240
|
+
@dav.tag! "D:response" do
|
241
|
+
@dav.tag! "D:href", href
|
185
242
|
yield @dav
|
186
243
|
end
|
187
244
|
end
|
@@ -16,36 +16,18 @@ end
|
|
16
16
|
# ATTENTION: adapt this to newer rails version if upgrading the framework!
|
17
17
|
class ActionDispatch::Routing::Mapper
|
18
18
|
module HttpHelpers
|
19
|
-
def dav_propfind(*args, &block)
|
20
|
-
map_method(:propfind, *args, &block)
|
21
|
-
end
|
22
|
-
|
23
|
-
def dav_options(*args, &block)
|
24
|
-
map_method(:options, *args, &block)
|
25
|
-
end
|
26
|
-
|
27
|
-
def dav_copy(*args, &block)
|
28
|
-
map_method(:copy, *args, &block)
|
29
|
-
end
|
30
|
-
|
31
|
-
def dav_move(*args, &block)
|
32
|
-
map_method(:move, *args, &block)
|
33
|
-
end
|
34
19
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
def dav_proppatch(*args, &block)
|
48
|
-
map_method(:proppatch, *args, &block)
|
20
|
+
%w(propfind options copy move mkcol lock unlock proppatch).each do |method_name|
|
21
|
+
define_method "dav_#{method_name}" do |*args, &block|
|
22
|
+
case Rails.version
|
23
|
+
when /^3\./
|
24
|
+
map_method(method_name, *args, &block)
|
25
|
+
when /^4\./
|
26
|
+
map_method(method_name, args, &block)
|
27
|
+
else
|
28
|
+
raise "Your Rails Version (#{Rails.version}) is currently not supported by the RailsDAV gem."
|
29
|
+
end
|
30
|
+
end
|
49
31
|
end
|
50
32
|
end
|
51
33
|
|
@@ -95,7 +77,7 @@ class ActionDispatch::Routing::Mapper
|
|
95
77
|
end
|
96
78
|
|
97
79
|
def dav_options_response(*allowed_http_verbs)
|
98
|
-
proc { [200, {'Allow' => allowed_http_verbs.flatten.map{|s| s.to_s.upcase}.join(' '), 'DAV' => '1'}, ['']] }
|
80
|
+
proc { [200, {'Allow' => allowed_http_verbs.flatten.map{|s| s.to_s.upcase}.join(' '), 'DAV' => '1'}, [' ']] }
|
99
81
|
end
|
100
82
|
|
101
83
|
def dav_match(*args)
|
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: railsdav
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.8
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Willem van Kerkhof
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2015-09-10 00:00:00.000000000 Z
|
13
12
|
dependencies: []
|
14
13
|
description: Provides basic Rails 3/Rails 4 extensions for making your business resources
|
15
14
|
accessible via WebDAV. This gem does by no means by no means implement the full
|
@@ -23,35 +22,34 @@ files:
|
|
23
22
|
- README.md
|
24
23
|
- init.rb
|
25
24
|
- lib/railsdav.rb
|
26
|
-
- lib/railsdav/routing_extensions.rb
|
27
|
-
- lib/railsdav/request_extensions.rb
|
28
|
-
- lib/railsdav/renderer/response_collector.rb
|
29
|
-
- lib/railsdav/renderer/response_type_selector.rb
|
30
25
|
- lib/railsdav/controller_extensions.rb
|
31
26
|
- lib/railsdav/renderer.rb
|
27
|
+
- lib/railsdav/renderer/response_collector.rb
|
28
|
+
- lib/railsdav/renderer/response_type_selector.rb
|
29
|
+
- lib/railsdav/request_extensions.rb
|
30
|
+
- lib/railsdav/routing_extensions.rb
|
32
31
|
homepage: http://github.com/wvk/railsdav
|
33
|
-
licenses:
|
32
|
+
licenses:
|
33
|
+
- MIT
|
34
|
+
metadata: {}
|
34
35
|
post_install_message:
|
35
36
|
rdoc_options: []
|
36
37
|
require_paths:
|
37
38
|
- lib
|
38
39
|
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
-
none: false
|
40
40
|
requirements:
|
41
|
-
- -
|
41
|
+
- - ">="
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
version: '0'
|
44
44
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
-
none: false
|
46
45
|
requirements:
|
47
|
-
- -
|
46
|
+
- - ">="
|
48
47
|
- !ruby/object:Gem::Version
|
49
48
|
version: '0'
|
50
49
|
requirements: []
|
51
50
|
rubyforge_project:
|
52
|
-
rubygems_version:
|
51
|
+
rubygems_version: 2.2.0
|
53
52
|
signing_key:
|
54
|
-
specification_version:
|
53
|
+
specification_version: 4
|
55
54
|
summary: Make your Rails 3/4 resources accessible via WebDAV
|
56
55
|
test_files: []
|
57
|
-
has_rdoc:
|