Class: RackDAV::Controller

Inherits:
Object
  • Object
show all
Includes:
HTTPStatus
Defined in:
lib/rack_dav/controller.rb

Constant Summary

Constants included from HTTPStatus

HTTPStatus::StatusMessage

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(request, response, options) ⇒ Controller

Returns a new instance of Controller.

Raises:

  • (Forbidden)


12
13
14
15
16
17
18
# File 'lib/rack_dav/controller.rb', line 12

def initialize(request, response, options)
  @request  = request
  @response = response
  @options  = options
  @resource = resource_class.new(url_unescape(request.path_info), @request, @response, @options)
  raise Forbidden if request.path_info.include?('../')
end

Instance Attribute Details

#requestObject (readonly)

Returns the value of attribute request.



10
11
12
# File 'lib/rack_dav/controller.rb', line 10

def request
  @request
end

#resourceObject (readonly)

Returns the value of attribute resource.



10
11
12
# File 'lib/rack_dav/controller.rb', line 10

def resource
  @resource
end

#responseObject (readonly)

Returns the value of attribute response.



10
11
12
# File 'lib/rack_dav/controller.rb', line 10

def response
  @response
end

Instance Method Details

#copyObject



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/rack_dav/controller.rb', line 91

def copy
  raise NotFound if not resource.exist?

  dest_uri = URI.parse(env['HTTP_DESTINATION'])
  destination = url_unescape(dest_uri.path)

  raise BadGateway if dest_uri.host and dest_uri.host != request.host
  raise Forbidden if destination == resource.path

  dest = resource_class.new(destination, @request, @response, @options)
  dest = dest.child(resource.name) if dest.collection?

  dest_existed = dest.exist?

  copy_recursive(resource, dest, depth, errors = [])

  if errors.empty?
    response.status = dest_existed ? NoContent : Created
  else
    multistatus do |xml|
      response_errors(xml, errors)
    end
  end
rescue URI::InvalidURIError => e
  raise BadRequest.new(e.message)
end

#deleteObject



72
73
74
75
76
77
78
79
80
81
82
# File 'lib/rack_dav/controller.rb', line 72

def delete
  delete_recursive(resource, errors = [])

  if errors.empty?
    response.status = NoContent
  else
    multistatus do |xml|
      response_errors(xml, errors)
    end
  end
end

#getObject

Raises:

  • (NotFound)


48
49
50
51
52
53
54
55
56
57
# File 'lib/rack_dav/controller.rb', line 48

def get
  raise NotFound if not 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
  map_exceptions do
    resource.get
  end
end

#headObject

Raises:

  • (NotFound)


40
41
42
43
44
45
46
# File 'lib/rack_dav/controller.rb', line 40

def head
  raise NotFound if not 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
end

#lockObject

Raises:

  • (MethodNotAllowed)


188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/rack_dav/controller.rb', line 188

def lock
  raise MethodNotAllowed unless resource.lockable?
  raise NotFound if not resource.exist?

  timeout = request_timeout
  if timeout.nil? || timeout.zero?
    timeout = 60
  end

  if request_document.content.empty?
    refresh_lock timeout
  else
    create_lock timeout
  end
end

#mkcolObject



84
85
86
87
88
89
# File 'lib/rack_dav/controller.rb', line 84

def mkcol
  map_exceptions do
    resource.make_collection
  end
  response.status = Created
end

#moveObject



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/rack_dav/controller.rb', line 118

def move
  raise NotFound if not resource.exist?

  dest_uri = URI.parse(env['HTTP_DESTINATION'])
  destination = url_unescape(dest_uri.path)

  raise BadGateway if dest_uri.host and dest_uri.host != request.host
  raise Forbidden if destination == resource.path

  dest = resource_class.new(destination, @request, @response, @options)
  dest = dest.child(resource.name) if dest.collection?

  dest_existed = dest.exist?

  raise Conflict if depth <= 1

  copy_recursive(resource, dest, depth, errors = [])
  delete_recursive(resource, errors)

  if errors.empty?
    response.status = dest_existed ? NoContent : Created
  else
    multistatus do |xml|
      response_errors(xml, errors)
    end
  end
rescue URI::InvalidURIError => e
  raise BadRequest.new(e.message)
end

#optionsObject



28
29
30
31
32
33
34
35
36
37
38
# File 'lib/rack_dav/controller.rb', line 28

def options
  response["Allow"] = 'OPTIONS,HEAD,GET,PUT,POST,DELETE,PROPFIND,PROPPATCH,MKCOL,COPY,MOVE'
  response["Dav"] = "1"

  if resource.lockable?
    response["Allow"] << ",LOCK,UNLOCK"
    response["Dav"]   << ",2"
  end

  response["Ms-Author-Via"] = "DAV"
end

#postObject



66
67
68
69
70
# File 'lib/rack_dav/controller.rb', line 66

def post
  map_exceptions do
    resource.post
  end
end

#propfindObject

Raises:

  • (NotFound)


148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/rack_dav/controller.rb', line 148

def propfind
  raise NotFound if not resource.exist?

  if not request_match("/d:propfind/d:allprop").empty?
    names = resource.property_names
  else
    names = request_match("/d:propfind/d:prop/d:*").map { |e| e.name }
    names = resource.property_names if names.empty?
    raise BadRequest if names.empty?
  end

  multistatus do |xml|
    for resource in find_resources
      resource.path.gsub!(/\/\//, '/')
      xml.response do
        xml.href "http://#{host}#{url_escape resource.path}"
        propstats xml, get_properties(resource, names)
      end
    end
  end
end

#proppatchObject

Raises:

  • (NotFound)


170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/rack_dav/controller.rb', line 170

def proppatch
  raise NotFound if not resource.exist?

  prop_rem = request_match("/d:propertyupdate/d:remove/d:prop/d:*").map { |e| [e.name] }
  prop_set = request_match("/d:propertyupdate/d:set/d:prop/d:*").map { |e| [e.name, e.text] }

  multistatus do |xml|
    for resource in find_resources
      xml.response do
        xml.href "http://#{host}#{resource.path}"
        propstats xml, set_properties(resource, prop_set)
      end
    end
  end

  resource.save
end

#putObject

Raises:

  • (Forbidden)


59
60
61
62
63
64
# File 'lib/rack_dav/controller.rb', line 59

def put
  raise Forbidden if resource.collection?
  map_exceptions do
    resource.put
  end
end

#unlockObject

Raises:

  • (MethodNotAllowed)


204
205
206
207
208
209
210
211
# File 'lib/rack_dav/controller.rb', line 204

def unlock
  raise MethodNotAllowed unless resource.lockable?

  locktoken = request_locktoken('LOCK_TOKEN')
  raise BadRequest if locktoken.nil?

  response.status = resource.unlock(locktoken) ? NoContent : Forbidden
end

#url_escape(s) ⇒ Object



20
21
22
# File 'lib/rack_dav/controller.rb', line 20

def url_escape(s)
  URI.escape(s)
end

#url_unescape(s) ⇒ Object



24
25
26
# File 'lib/rack_dav/controller.rb', line 24

def url_unescape(s)
  URI.unescape(s).force_valid_encoding
end