Merge pull request #939 from ahorek/dav4rack

dav4rack 1.1.0
This commit is contained in:
Karel Picman 2019-01-03 10:02:11 +01:00 committed by GitHub
commit e830d6c9b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 28 deletions

View File

@ -102,12 +102,14 @@ module DAV4Rack
# Return response to HEAD
def head
if(resource.exist?)
response['Etag'] = resource.etag
response['Content-Type'] = resource.content_type
response['Content-Length'] = resource.content_length.to_s
response['Last-Modified'] = resource.last_modified.httpdate
resource.head(request, response)
OK
res = resource.head(request, response)
if(res == OK)
response['Etag'] ||= resource.etag
response['Content-Type'] ||= resource.content_type
response['Content-Length'] ||= resource.content_length.to_s
response['Last-Modified'] ||= resource.last_modified.httpdate
end
res
else
NotFound
end
@ -197,7 +199,8 @@ module DAV4Rack
return BadRequest unless request.depth == :infinity
return BadRequest unless dest = request.destination
if status = dest.validate
if status = dest.validate(host: request.host,
resource_path: resource.path)
return status
end

View File

@ -5,24 +5,13 @@ module DAV4Rack
attr_reader :host, :path, :path_info
def initialize(value, script_name: nil)
@script_name = script_name.to_s
@value = value.to_s.strip
parse
end
def parse
uri = Addressable::URI.parse @value
# uri is expected to be a DAV4Rack::Uri instance
def initialize(uri)
@host = uri.host
@path = Addressable::URI.unencode uri.path
if @script_name
if @path =~ /\A(?<path>#{Regexp.escape @script_name}(?<path_info>\/.*))\z/
@path_info = $~[:path_info]
else
raise ArgumentError, 'invalid destination header value'
end
@path = uri.path
unless @path_info = uri.path_info
# nil path info means path is outside the realm of script_name
raise ArgumentError, "invalid destination header value: #{uri.to_s}"
end
end
@ -30,7 +19,7 @@ module DAV4Rack
def validate(host: nil, resource_path: nil)
if host and self.host and self.host != host
DAV4Rack::HTTPStatus::BadGateway
elsif self.path == resource_path
elsif resource_path and self.path_info == resource_path
DAV4Rack::HTTPStatus::Forbidden
end
end

View File

@ -3,6 +3,7 @@
require 'uri'
require 'addressable/uri'
require 'dav4rack/logger'
require 'dav4rack/uri'
module DAV4Rack
class Request < Rack::Request
@ -84,7 +85,7 @@ module DAV4Rack
# Destination header
def destination
@destination ||= if h = get_header('HTTP_DESTINATION')
DestinationHeader.new h, script_name: script_name
DestinationHeader.new DAV4Rack::Uri.new(h, script_name: script_name)
end
end
@ -123,6 +124,13 @@ module DAV4Rack
"#{script_name}#{expand_path path}"
end
# returns the given path, but with the leading script_name removed. Will
# return nil if the path does not begin with the script_name
def path_info_for(full_path, script_name: self.script_name)
uri = DAV4Rack::Uri.new full_path, script_name: script_name
return uri.path_info
end
# expands '/foo/../bar' to '/bar'
def expand_path(path)
path.squeeze! '/'

View File

@ -208,8 +208,12 @@ module DAV4Rack
NotImplemented
end
# HTTP HEAD request.
#
# Like GET, but without content. Override if you set custom headers in GET
# to set them here as well.
def head(request, response)
#no-op, but called by the controller
OK
end
# HTTP PUT request.

42
lib/dav4rack/uri.rb Normal file
View File

@ -0,0 +1,42 @@
require 'addressable/uri'
module DAV4Rack
# adds a bit of parsing logic around a header URI or path value
class Uri
attr_reader :host, :path, :path_info, :script_name
def initialize(uri_or_path, script_name: nil)
# more than one leading slash confuses Addressable::URI, resulting e.g.
# with //remote.php/dav/files in a path of /dav/files with a host
# remote.php.
@uri_or_path = uri_or_path.to_s.strip.sub %r{\A/+}, '/'
@script_name = script_name
parse
end
def to_s
@uri_or_path
end
private
def parse
uri = Addressable::URI.parse @uri_or_path
@host = uri.host
@path = Addressable::URI.unencode uri.path
if @script_name
if @path =~ /\A(?<path>#{Regexp.escape @script_name}(?<path_info>\/.*))\z/
@path_info = $~[:path_info]
end
else
@path_info = @path
end
end
end
end

View File

@ -13,5 +13,5 @@ module DAV4Rack
end
end
VERSION = Version.new('1.0.0')
VERSION = Version.new('1.1.0')
end