rack-webdav 0.4.2 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9025207ede1c1f829fa216898d173661ac29aa2d
|
4
|
+
data.tar.gz: e6c001a417788e6a4134493ecb82031467c3ebaa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1be317ee0340db32fa1ebf40f663810b58fc50b29a3d08f7c9c745a2912d67849639ac9a4dde236e065119e7f83e90e8fb5b3f69160f90a61e07dd5bb226ac71
|
7
|
+
data.tar.gz: e01078ed80e0a6fb2ec0dd99c4c89fa4765a6c1a43d001083935031ac6a9191bd0bc179ec101ab320e8d39d67b5d0526e0b7660098c8b3b12807c47bae140e38
|
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'uri'
|
2
2
|
|
3
3
|
module RackWebDAV
|
4
|
-
|
4
|
+
|
5
5
|
class Controller
|
6
6
|
include RackWebDAV::HTTPStatus
|
7
7
|
include RackWebDAV::Utils
|
8
|
-
|
8
|
+
|
9
9
|
attr_reader :request, :response, :resource
|
10
10
|
|
11
11
|
# request:: Rack::Request
|
@@ -18,17 +18,17 @@ module RackWebDAV
|
|
18
18
|
@request = request
|
19
19
|
@response = response
|
20
20
|
@options = options
|
21
|
-
|
21
|
+
|
22
22
|
@dav_extensions = options.delete(:dav_extensions) || []
|
23
23
|
@always_include_dav_header = options.delete(:always_include_dav_header)
|
24
|
-
|
24
|
+
|
25
25
|
@resource = resource_class.new(actual_path, implied_path, @request, @response, @options)
|
26
|
-
|
26
|
+
|
27
27
|
if(@always_include_dav_header)
|
28
28
|
add_dav_header
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
# s:: string
|
33
33
|
# Escape URL string
|
34
34
|
def url_format(resource)
|
@@ -38,20 +38,20 @@ module RackWebDAV
|
|
38
38
|
end
|
39
39
|
ret
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
# s:: string
|
43
43
|
# Unescape URL string
|
44
|
-
def url_unescape(s)
|
45
|
-
URI.
|
44
|
+
def url_unescape(s, encoding = Encoding::UTF_8)
|
45
|
+
URI.decode_www_form_component(s, encoding)
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def add_dav_header
|
49
49
|
unless(response['Dav'])
|
50
50
|
dav_support = %w(1 2) + @dav_extensions
|
51
51
|
response['Dav'] = dav_support.join(', ')
|
52
52
|
end
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
# Return response to OPTIONS
|
56
56
|
def options
|
57
57
|
add_dav_header
|
@@ -59,7 +59,7 @@ module RackWebDAV
|
|
59
59
|
response['Ms-Author-Via'] = 'DAV'
|
60
60
|
OK
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
# Return response to HEAD
|
64
64
|
def head
|
65
65
|
if(resource.exist?)
|
@@ -71,7 +71,7 @@ module RackWebDAV
|
|
71
71
|
NotFound
|
72
72
|
end
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
# Return response to GET
|
76
76
|
def get
|
77
77
|
if(resource.exist?)
|
@@ -117,7 +117,7 @@ module RackWebDAV
|
|
117
117
|
NotFound
|
118
118
|
end
|
119
119
|
end
|
120
|
-
|
120
|
+
|
121
121
|
# Return response to MKCOL
|
122
122
|
def mkcol
|
123
123
|
resource.lock_check if resource.supports_locking?
|
@@ -135,7 +135,7 @@ module RackWebDAV
|
|
135
135
|
status
|
136
136
|
end
|
137
137
|
end
|
138
|
-
|
138
|
+
|
139
139
|
# Return response to COPY
|
140
140
|
def copy
|
141
141
|
move(:copy)
|
@@ -180,7 +180,7 @@ module RackWebDAV
|
|
180
180
|
end
|
181
181
|
end
|
182
182
|
end
|
183
|
-
|
183
|
+
|
184
184
|
# Return response to PROPFIND
|
185
185
|
def propfind
|
186
186
|
unless(resource.exist?)
|
@@ -189,25 +189,28 @@ module RackWebDAV
|
|
189
189
|
unless(request_document.xpath("//#{ns}propfind/#{ns}allprop").empty?)
|
190
190
|
properties = resource.properties
|
191
191
|
else
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
192
|
+
if request.body.read.bytesize > 0
|
193
|
+
request.body.rewind
|
194
|
+
check = request_document.xpath("//#{ns}propfind")
|
195
|
+
if(check && !check.empty?)
|
196
|
+
properties = request_document.xpath(
|
197
|
+
"//#{ns}propfind/#{ns}prop"
|
198
|
+
).children.find_all{ |item|
|
199
|
+
item.element?
|
200
|
+
}.map{ |item|
|
201
|
+
# We should do this, but Nokogiri transforms prefix w/ null href into
|
202
|
+
# something valid. Oops.
|
203
|
+
# TODO: Hacky grep fix that's horrible
|
204
|
+
hsh = to_element_hash(item)
|
205
|
+
if(hsh.namespace.nil? && !ns.empty?)
|
206
|
+
raise BadRequest if request_document.to_s.scan(%r{<#{item.name}[^>]+xmlns=""}).empty?
|
207
|
+
end
|
208
|
+
hsh
|
209
|
+
}.compact
|
210
|
+
else
|
211
|
+
raise BadRequest
|
212
|
+
end
|
208
213
|
else
|
209
|
-
# XXX: Compatibility for Windows.
|
210
|
-
# raise BadRequest
|
211
214
|
properties = []
|
212
215
|
end
|
213
216
|
end
|
@@ -225,7 +228,7 @@ module RackWebDAV
|
|
225
228
|
end
|
226
229
|
end
|
227
230
|
end
|
228
|
-
|
231
|
+
|
229
232
|
# Return response to PROPPATCH
|
230
233
|
def proppatch
|
231
234
|
unless(resource.exist?)
|
@@ -266,7 +269,7 @@ module RackWebDAV
|
|
266
269
|
|
267
270
|
# Lock current resource
|
268
271
|
# NOTE: This will pass an argument hash to Resource#lock and
|
269
|
-
# wait for a success/failure response.
|
272
|
+
# wait for a success/failure response.
|
270
273
|
def lock
|
271
274
|
lockinfo = request_document.xpath("//#{ns}lockinfo")
|
272
275
|
asked = {}
|
@@ -344,29 +347,29 @@ module RackWebDAV
|
|
344
347
|
end
|
345
348
|
raise Unauthorized unless authed
|
346
349
|
end
|
347
|
-
|
350
|
+
|
348
351
|
private
|
349
352
|
|
350
353
|
# Request environment variables
|
351
354
|
def env
|
352
355
|
@request.env
|
353
356
|
end
|
354
|
-
|
357
|
+
|
355
358
|
# Current request scheme (http/https)
|
356
359
|
def scheme
|
357
360
|
request.scheme
|
358
361
|
end
|
359
|
-
|
362
|
+
|
360
363
|
# Request host
|
361
364
|
def host
|
362
365
|
request.host
|
363
366
|
end
|
364
|
-
|
367
|
+
|
365
368
|
# Request port
|
366
369
|
def port
|
367
370
|
request.port
|
368
371
|
end
|
369
|
-
|
372
|
+
|
370
373
|
# Class of the resource in use
|
371
374
|
def resource_class
|
372
375
|
@options[:resource_class]
|
@@ -376,12 +379,12 @@ module RackWebDAV
|
|
376
379
|
def root_uri_path
|
377
380
|
@options[:root_uri_path]
|
378
381
|
end
|
379
|
-
|
382
|
+
|
380
383
|
# Returns Resource path with root URI removed
|
381
384
|
def implied_path
|
382
385
|
clean_path(@request.path.dup)
|
383
386
|
end
|
384
|
-
|
387
|
+
|
385
388
|
# x:: request path
|
386
389
|
# Unescapes path and removes root URI if applicable
|
387
390
|
def clean_path(x)
|
@@ -389,7 +392,7 @@ module RackWebDAV
|
|
389
392
|
ip.gsub!(/^#{Regexp.escape(root_uri_path)}/, '') if root_uri_path
|
390
393
|
ip
|
391
394
|
end
|
392
|
-
|
395
|
+
|
393
396
|
# Unescaped request path
|
394
397
|
def actual_path
|
395
398
|
url_unescape(@request.path.dup)
|
@@ -399,7 +402,7 @@ module RackWebDAV
|
|
399
402
|
def lock_token
|
400
403
|
env['HTTP_LOCK_TOKEN'] || nil
|
401
404
|
end
|
402
|
-
|
405
|
+
|
403
406
|
# Requested depth
|
404
407
|
def depth
|
405
408
|
d = env['HTTP_DEPTH']
|
@@ -415,7 +418,7 @@ module RackWebDAV
|
|
415
418
|
def http_version
|
416
419
|
env['HTTP_VERSION'] || env['SERVER_PROTOCOL'] || 'HTTP/1.0'
|
417
420
|
end
|
418
|
-
|
421
|
+
|
419
422
|
# Overwrite is allowed
|
420
423
|
def overwrite
|
421
424
|
env['HTTP_OVERWRITE'].to_s.upcase != 'F'
|
@@ -434,9 +437,10 @@ module RackWebDAV
|
|
434
437
|
end
|
435
438
|
with_current_resource ? [resource] + ary : ary
|
436
439
|
end
|
437
|
-
|
440
|
+
|
438
441
|
# XML parsed request
|
439
442
|
def request_document
|
443
|
+
request.body.rewind
|
440
444
|
@request_document ||= Nokogiri.XML(request.body.read)
|
441
445
|
rescue
|
442
446
|
raise BadRequest
|
@@ -458,7 +462,7 @@ module RackWebDAV
|
|
458
462
|
end
|
459
463
|
_ns
|
460
464
|
end
|
461
|
-
|
465
|
+
|
462
466
|
# root_type:: Root tag name
|
463
467
|
# Render XML and set Rack::Response#body= to final XML
|
464
468
|
def render_xml(root_type)
|
@@ -470,7 +474,7 @@ module RackWebDAV
|
|
470
474
|
yield xml
|
471
475
|
end
|
472
476
|
end
|
473
|
-
|
477
|
+
|
474
478
|
if(@options[:pretty_xml])
|
475
479
|
response.body = doc.to_xml
|
476
480
|
else
|
@@ -481,7 +485,7 @@ module RackWebDAV
|
|
481
485
|
response["Content-Type"] = 'text/xml; charset="utf-8"'
|
482
486
|
response["Content-Length"] = response.body.size.to_s
|
483
487
|
end
|
484
|
-
|
488
|
+
|
485
489
|
# block:: block
|
486
490
|
# Creates a multistatus response using #render_xml and
|
487
491
|
# returns the correct status
|
@@ -489,7 +493,7 @@ module RackWebDAV
|
|
489
493
|
render_xml(:multistatus, &block)
|
490
494
|
MultiStatus
|
491
495
|
end
|
492
|
-
|
496
|
+
|
493
497
|
# xml:: Nokogiri::XML::Builder
|
494
498
|
# errors:: Array of errors
|
495
499
|
# Crafts responses for errors
|
@@ -545,7 +549,7 @@ module RackWebDAV
|
|
545
549
|
end
|
546
550
|
stats
|
547
551
|
end
|
548
|
-
|
552
|
+
|
549
553
|
# xml:: Nokogiri::XML::Builder
|
550
554
|
# stats:: Array of stats
|
551
555
|
# Build propstats response
|
@@ -590,14 +594,12 @@ module RackWebDAV
|
|
590
594
|
end
|
591
595
|
end
|
592
596
|
end
|
593
|
-
|
597
|
+
|
594
598
|
# xml:: Nokogiri::XML::Builder
|
595
599
|
# element:: Nokogiri::XML::Element
|
596
600
|
# Converts element into proper text
|
597
601
|
def xml_convert(xml, element)
|
598
602
|
xml.doc.root.add_child(element)
|
599
603
|
end
|
600
|
-
|
601
604
|
end
|
602
|
-
|
603
|
-
end
|
605
|
+
end
|
data/lib/rack-webdav/handler.rb
CHANGED
@@ -181,7 +181,7 @@ module RackWebDAV
|
|
181
181
|
if(::File.directory?(file_path))
|
182
182
|
MethodNotAllowed
|
183
183
|
else
|
184
|
-
if(::File.directory?(::File.dirname(file_path)) && !::File.exists?(file_path))
|
184
|
+
if(::File.directory?(::File.dirname(file_path)) && !::File.exists?(file_path) && !::File.exists?(file_path.gsub(/\/$/, '')))
|
185
185
|
Dir.mkdir(file_path)
|
186
186
|
Created
|
187
187
|
else
|
@@ -299,7 +299,12 @@ module RackWebDAV
|
|
299
299
|
end
|
300
300
|
raise failure
|
301
301
|
else
|
302
|
-
|
302
|
+
if @user.respond_to?(:id)
|
303
|
+
locks = FileResourceLock.implict_locks(@path).find(:all, :conditions => ["scope = 'exclusive' AND user_id != ?", @user.id])
|
304
|
+
else
|
305
|
+
locks = []
|
306
|
+
end
|
307
|
+
|
303
308
|
if(locks.size > 0)
|
304
309
|
failure = LockFailure.new("Failed to lock: #{@path}")
|
305
310
|
locks.each do |lock|
|
data/lib/rack-webdav/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-webdav
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Koki Oyatsu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-05-
|
11
|
+
date: 2017-05-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -176,7 +176,6 @@ files:
|
|
176
176
|
- lib/rack-webdav/remote_file.rb
|
177
177
|
- lib/rack-webdav/resource.rb
|
178
178
|
- lib/rack-webdav/resources/file_resource.rb
|
179
|
-
- lib/rack-webdav/resources/mongo_resource.rb
|
180
179
|
- lib/rack-webdav/utils.rb
|
181
180
|
- lib/rack-webdav/version.rb
|
182
181
|
- rack-webdav.gemspec
|
@@ -1,341 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
require 'mime/types'
|
3
|
-
|
4
|
-
module RackWebDAV
|
5
|
-
|
6
|
-
class MongoResource < RackWebDAV::Resource
|
7
|
-
|
8
|
-
# @@logger = Rails.logger
|
9
|
-
|
10
|
-
def initialize(public_path, path, request, response, options)
|
11
|
-
# 'ASCII-8BIT'で渡される場合があるので'UTF-8'を指定しておく
|
12
|
-
_force_encoding!(public_path)
|
13
|
-
_force_encoding!(path)
|
14
|
-
super(public_path, path, request, response, options)
|
15
|
-
@filesystem = Mongo::GridFileSystem.new(Mongoid.database)
|
16
|
-
@collection = Mongoid.database.collection('fs.files')
|
17
|
-
if options[:bson]
|
18
|
-
@bson = options[:bson]
|
19
|
-
elsif path.length <= 1
|
20
|
-
# ルートの場合 (''の場合と'/'の場合がある)
|
21
|
-
@bson = {'filename' => root + '/'}
|
22
|
-
else
|
23
|
-
# ファイルかディレクトリが、パラメータだけでは判断できない。ので \/? が必要。
|
24
|
-
# だから、ディレクトリと同名のファイルは、作成できない。
|
25
|
-
@bson = @collection.find_one({:filename => /^#{Regexp.escape(file_path)}\/?$/}) rescue nil
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def child(bson)
|
30
|
-
path = remove(bson['filename'], root)
|
31
|
-
public_path = @options[:root_uri_path] + path
|
32
|
-
@options[:bson] = bson
|
33
|
-
self.class.new(public_path, path, @request, @response, @options)
|
34
|
-
end
|
35
|
-
|
36
|
-
# If this is a collection, return the child resources.
|
37
|
-
def children
|
38
|
-
# Dir[file_path + '/*'].map do |path|
|
39
|
-
# child File.basename(path)
|
40
|
-
# end
|
41
|
-
@collection.find({:filename => /^#{Regexp.escape(@bson['filename'])}[^\/]+\/?$/}).map do |bson|
|
42
|
-
child bson
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Is this resource a collection?
|
47
|
-
def collection?
|
48
|
-
# File.directory?(file_path)
|
49
|
-
@bson && _collection?(@bson['filename'])
|
50
|
-
end
|
51
|
-
|
52
|
-
# Does this recource exist?
|
53
|
-
def exist?
|
54
|
-
# File.exist?(file_path)
|
55
|
-
@bson
|
56
|
-
end
|
57
|
-
|
58
|
-
# Return the creation time.
|
59
|
-
def creation_date
|
60
|
-
# stat.ctime
|
61
|
-
@bson['uploadDate'] || Date.new
|
62
|
-
end
|
63
|
-
|
64
|
-
# Return the time of last modification.
|
65
|
-
def last_modified
|
66
|
-
# stat.mtime
|
67
|
-
@bson['uploadDate'] || Date.new
|
68
|
-
end
|
69
|
-
|
70
|
-
# Set the time of last modification.
|
71
|
-
def last_modified=(time)
|
72
|
-
# File.utime(Time.now, time, file_path)
|
73
|
-
end
|
74
|
-
|
75
|
-
# Return an Etag, an unique hash value for this resource.
|
76
|
-
def etag
|
77
|
-
# sprintf('%x-%x-%x', stat.ino, stat.size, stat.mtime.to_i)
|
78
|
-
@bson['_id'].to_s
|
79
|
-
end
|
80
|
-
|
81
|
-
# Return the mime type of this resource.
|
82
|
-
def content_type
|
83
|
-
# if stat.directory?
|
84
|
-
# "text/html"
|
85
|
-
# else
|
86
|
-
# mime_type(file_path, DefaultMimeTypes)
|
87
|
-
# end
|
88
|
-
@bson['contentType'] || "text/html"
|
89
|
-
end
|
90
|
-
|
91
|
-
# Return the size in bytes for this resource.
|
92
|
-
def content_length
|
93
|
-
# stat.size
|
94
|
-
@bson['length'] || 0
|
95
|
-
end
|
96
|
-
|
97
|
-
# HTTP GET request.
|
98
|
-
#
|
99
|
-
# Write the content of the resource to the response.body.
|
100
|
-
def get(request, response)
|
101
|
-
raise NotFound unless exist?
|
102
|
-
# if stat.directory?
|
103
|
-
# response.body = ""
|
104
|
-
# Rack::Directory.new(root).call(request.env)[2].each do |line|
|
105
|
-
# response.body << line
|
106
|
-
# end
|
107
|
-
# response['Content-Length'] = response.body.size.to_s
|
108
|
-
# else
|
109
|
-
# file = Rack::File.new(root)
|
110
|
-
# response.body = file
|
111
|
-
# end
|
112
|
-
if collection?
|
113
|
-
response.body = "<html>"
|
114
|
-
response.body << "<h2>" + file_path.html_safe + "</h2>"
|
115
|
-
children.each do |child|
|
116
|
-
name = child.file_path.html_safe
|
117
|
-
path = child.public_path
|
118
|
-
response.body << "<a href='" + path + "'>" + name + "</a>"
|
119
|
-
response.body << "</br>"
|
120
|
-
end
|
121
|
-
response.body << "</html>"
|
122
|
-
response['Content-Length'] = response.body.size.to_s
|
123
|
-
response['Content-Type'] = 'text/html'
|
124
|
-
else
|
125
|
-
@filesystem.open(file_path, 'r') do |f|
|
126
|
-
response.body = f
|
127
|
-
response['Content-Type'] = @bson['contentType']
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
end
|
132
|
-
|
133
|
-
# HTTP PUT request.
|
134
|
-
#
|
135
|
-
# Save the content of the request.body.
|
136
|
-
def put(request, response)
|
137
|
-
write(request.body)
|
138
|
-
Created
|
139
|
-
end
|
140
|
-
|
141
|
-
# HTTP POST request.
|
142
|
-
#
|
143
|
-
# Usually forbidden.
|
144
|
-
def post(request, response)
|
145
|
-
raise HTTPStatus::Forbidden
|
146
|
-
end
|
147
|
-
|
148
|
-
# HTTP DELETE request.
|
149
|
-
#
|
150
|
-
# Delete this resource.
|
151
|
-
def delete
|
152
|
-
# if stat.directory?
|
153
|
-
# FileUtils.rm_rf(file_path)
|
154
|
-
# else
|
155
|
-
# File.unlink(file_path)
|
156
|
-
# end
|
157
|
-
if collection?
|
158
|
-
@collection.find({:filename => /^#{Regexp.escape(@bson['filename'])}/}).each do |bson|
|
159
|
-
@collection.remove(bson)
|
160
|
-
end
|
161
|
-
else
|
162
|
-
@collection.remove(@bson)
|
163
|
-
end
|
164
|
-
NoContent
|
165
|
-
end
|
166
|
-
|
167
|
-
# HTTP COPY request.
|
168
|
-
#
|
169
|
-
# Copy this resource to given destination resource.
|
170
|
-
def copy(dest, overwrite = false)
|
171
|
-
# if(dest.path == path)
|
172
|
-
# Conflict
|
173
|
-
# elsif(stat.directory?)
|
174
|
-
# dest.make_collection
|
175
|
-
# FileUtils.cp_r("#{file_path}/.", "#{dest.send(:file_path)}/")
|
176
|
-
# OK
|
177
|
-
# else
|
178
|
-
# exists = File.exists?(file_path)
|
179
|
-
# if(exists && !overwrite)
|
180
|
-
# PreconditionFailed
|
181
|
-
# else
|
182
|
-
# open(file_path, "rb") do |file|
|
183
|
-
# dest.write(file)
|
184
|
-
# end
|
185
|
-
# exists ? NoContent : Created
|
186
|
-
# end
|
187
|
-
# end
|
188
|
-
|
189
|
-
# ディレクトリなら末尾に「/」をつける。
|
190
|
-
# (dstにもともと「/」が付いているかどうか、クライアントに依存している)
|
191
|
-
# CarotDAV : 「/」が付いていない
|
192
|
-
# TeamFile : 「/」が付いている
|
193
|
-
dest.collection! if collection?
|
194
|
-
|
195
|
-
src = @bson['filename']
|
196
|
-
dst = dest.file_path
|
197
|
-
exists = nil
|
198
|
-
|
199
|
-
@collection.find({:filename => /^#{Regexp.escape(src)}/}).each do |bson|
|
200
|
-
src_name = bson['filename']
|
201
|
-
dst_name = dst + src_name.slice(src.length, src_name.length)
|
202
|
-
|
203
|
-
exists = @collection.find_one({:filename => dst_name}) rescue nil
|
204
|
-
|
205
|
-
return PreconditionFailed if (exists && !overwrite && !collection?)
|
206
|
-
|
207
|
-
@filesystem.open(src_name, "r") do |src|
|
208
|
-
@filesystem.open(dst_name, "w") do |dst|
|
209
|
-
dst.write(src) if src.file_length > 0
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
@collection.remove(exists) if exists
|
214
|
-
end
|
215
|
-
|
216
|
-
collection? ? Created : (exists ? NoContent : Created)
|
217
|
-
end
|
218
|
-
|
219
|
-
# HTTP MOVE request.
|
220
|
-
#
|
221
|
-
# Move this resource to given destination resource.
|
222
|
-
def move(dest, overwrite = false)
|
223
|
-
|
224
|
-
# ディレクトリなら末尾に「/」をつける。
|
225
|
-
# (dstにもともと「/」が付いているかどうか、クライアントに依存している)
|
226
|
-
# CarotDAV : 「/」が付いていない
|
227
|
-
# TeamFile : 「/」が付いている
|
228
|
-
dest.collection! if collection?
|
229
|
-
|
230
|
-
src = @bson['filename']
|
231
|
-
dst = dest.file_path
|
232
|
-
exists = nil
|
233
|
-
|
234
|
-
@collection.find({:filename => /^#{Regexp.escape(src)}/}).each do |bson|
|
235
|
-
src_name = bson['filename']
|
236
|
-
dst_name = dst + src_name.slice(src.length, src_name.length)
|
237
|
-
|
238
|
-
exists = @collection.find_one({:filename => dst_name}) rescue nil
|
239
|
-
|
240
|
-
# http://mongoid.org/docs/persistence/atomic.html
|
241
|
-
# http://rubydoc.info/github/mongoid/mongoid/master/Mongoid/Collection#update-instance_method
|
242
|
-
@collection.update({'_id' => bson['_id']}, {'$set' => {'filename' => dst_name}}, :safe => true)
|
243
|
-
|
244
|
-
@collection.remove(exists) if exists
|
245
|
-
end
|
246
|
-
|
247
|
-
collection? ? Created : (exists ? NoContent : Created)
|
248
|
-
end
|
249
|
-
|
250
|
-
# HTTP MKCOL request.
|
251
|
-
#
|
252
|
-
# Create this resource as collection.
|
253
|
-
def make_collection
|
254
|
-
# Dir.mkdir(file_path)
|
255
|
-
# Created
|
256
|
-
|
257
|
-
# ディレクトリなら末尾に「/」をつける。
|
258
|
-
# (dstにもともと「/」が付いているかどうか、クライアントに依存している)
|
259
|
-
# CarotDAV : 「/」が付いていない
|
260
|
-
# TeamFile : 「/」が付いている
|
261
|
-
collection!
|
262
|
-
|
263
|
-
bson = @collection.find_one({:filename => file_path}) rescue nil
|
264
|
-
|
265
|
-
# 0バイトのファイルを作成しディレクトリの代わりとする
|
266
|
-
@filesystem.open(file_path, "w") { |f| } if !bson
|
267
|
-
|
268
|
-
# @@logger.error('make_collection : ' + file_path)
|
269
|
-
|
270
|
-
Created
|
271
|
-
end
|
272
|
-
|
273
|
-
# Write to this resource from given IO.
|
274
|
-
def write(io)
|
275
|
-
# tempfile = "#{file_path}.#{Process.pid}.#{object_id}"
|
276
|
-
# open(tempfile, "wb") do |file|
|
277
|
-
# while part = io.read(8192)
|
278
|
-
# file << part
|
279
|
-
# end
|
280
|
-
# end
|
281
|
-
# File.rename(tempfile, file_path)
|
282
|
-
# ensure
|
283
|
-
# File.unlink(tempfile) rescue nil
|
284
|
-
|
285
|
-
# 同名のファイルができないように
|
286
|
-
bson = @collection.find_one({:filename => file_path}) rescue nil
|
287
|
-
|
288
|
-
@filesystem.open(file_path, "w", :content_type => _content_type(file_path)) { |f| f.write(io) }
|
289
|
-
|
290
|
-
# 同名のファイルができないように
|
291
|
-
@collection.remove(bson) if bson
|
292
|
-
|
293
|
-
end
|
294
|
-
|
295
|
-
protected
|
296
|
-
|
297
|
-
def file_path
|
298
|
-
root + path
|
299
|
-
end
|
300
|
-
|
301
|
-
# ファイル名の末尾に「/」を付加してディレクトリ(コレクション)とする
|
302
|
-
def collection!
|
303
|
-
path << '/' if !_collection?(path)
|
304
|
-
end
|
305
|
-
|
306
|
-
private
|
307
|
-
|
308
|
-
def _content_type(filename)
|
309
|
-
MIME::Types.type_for(filename).first.to_s || 'text/html'
|
310
|
-
end
|
311
|
-
|
312
|
-
def authenticate(user, pass)
|
313
|
-
if(options[:username])
|
314
|
-
options[:username] == user && options[:password] == pass
|
315
|
-
else
|
316
|
-
true
|
317
|
-
end
|
318
|
-
end
|
319
|
-
|
320
|
-
# path1の先頭からpath2を取り除く
|
321
|
-
def remove(path1, path2)
|
322
|
-
path1.slice(path2.length, path1.length)
|
323
|
-
end
|
324
|
-
|
325
|
-
def root
|
326
|
-
@options[:root]
|
327
|
-
end
|
328
|
-
|
329
|
-
# ファイル名の末尾が「/」のファイルをディレクトリ(コレクション)とする
|
330
|
-
def _collection?(path)
|
331
|
-
path && path[-1].chr == '/'
|
332
|
-
end
|
333
|
-
|
334
|
-
# 'ASCII-8BIT'で渡される場合があるので'UTF-8'を指定しておく
|
335
|
-
def _force_encoding!(str)
|
336
|
-
str.force_encoding('UTF-8')
|
337
|
-
end
|
338
|
-
|
339
|
-
end
|
340
|
-
|
341
|
-
end
|