dav4rack_ext 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/example/config.ru +1 -1
- data/lib/dav4rack_ext/carddav/app.rb +50 -11
- data/lib/dav4rack_ext/carddav/resources/principal_resource.rb +1 -14
- data/lib/dav4rack_ext/version.rb +1 -1
- data/specs/support/models.rb +2 -4
- data/specs/unit/carddav/resources/principal_resource_spec.rb +5 -4
- metadata +4 -4
data/Gemfile
CHANGED
data/example/config.ru
CHANGED
@@ -10,21 +10,28 @@ module DAV4Rack
|
|
10
10
|
current_user = opts.delete(:current_user)
|
11
11
|
root_uri_path = opts.delete(:root_uri_path) || root_path
|
12
12
|
|
13
|
-
if root_path[-1]
|
14
|
-
root_path
|
13
|
+
if (root_path != '/') && root_path[-1] == '/'
|
14
|
+
root_path.slice!(-1..-1)
|
15
15
|
end
|
16
16
|
|
17
17
|
raise "unknown options: #{opts}" unless opts.empty?
|
18
18
|
|
19
19
|
HttpRouter.new do |r|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
|
21
|
+
last_root_path_part = root_path.split('/').last
|
22
|
+
|
23
|
+
# try to help iOS find its way
|
24
|
+
r.add(%r{(?<root>.*/#{last_root_path_part})(?::[0-9]+)?/\.well(?:_|-)known/carddav/?}).to do |env|
|
25
|
+
|
26
|
+
headers = {
|
27
|
+
'Location' => env['router.params'][:root],
|
28
|
+
'Content-Type' => 'text/html',
|
29
|
+
}
|
30
|
+
|
31
|
+
[301, headers, []]
|
25
32
|
end
|
26
33
|
|
27
|
-
r.add("#{root_path}").to DAV4RackExt::Handler.new(
|
34
|
+
r.add("#{root_path}/").to DAV4RackExt::Handler.new(
|
28
35
|
:logger => logger,
|
29
36
|
:dav_extensions => DAV_EXTENSIONS,
|
30
37
|
:alway_include_dav_header => true,
|
@@ -38,7 +45,7 @@ module DAV4Rack
|
|
38
45
|
:books_collection => "/books/"
|
39
46
|
)
|
40
47
|
|
41
|
-
r.add("#{root_path}books/").to DAV4RackExt::Handler.new(
|
48
|
+
r.add("#{root_path}/books/").to DAV4RackExt::Handler.new(
|
42
49
|
:logger => logger,
|
43
50
|
:dav_extensions => DAV_EXTENSIONS,
|
44
51
|
:alway_include_dav_header => true,
|
@@ -49,7 +56,7 @@ module DAV4Rack
|
|
49
56
|
:current_user => current_user
|
50
57
|
)
|
51
58
|
|
52
|
-
r.add("#{root_path}books/:book_id/:contact_id(.vcf)").to DAV4RackExt::Handler.new(
|
59
|
+
r.add("#{root_path}/books/:book_id/:contact_id(.vcf)").to DAV4RackExt::Handler.new(
|
53
60
|
:logger => logger,
|
54
61
|
:dav_extensions => DAV_EXTENSIONS,
|
55
62
|
:alway_include_dav_header => true,
|
@@ -60,7 +67,7 @@ module DAV4Rack
|
|
60
67
|
:current_user => current_user
|
61
68
|
)
|
62
69
|
|
63
|
-
r.add("#{root_path}books/:book_id").to DAV4RackExt::Handler.new(
|
70
|
+
r.add("#{root_path}/books/:book_id").to DAV4RackExt::Handler.new(
|
64
71
|
:logger => logger,
|
65
72
|
:dav_extensions => DAV_EXTENSIONS,
|
66
73
|
:alway_include_dav_header => true,
|
@@ -71,6 +78,38 @@ module DAV4Rack
|
|
71
78
|
:current_user => current_user
|
72
79
|
)
|
73
80
|
|
81
|
+
# Another hack for iOS 6
|
82
|
+
#
|
83
|
+
r.default ->(env){
|
84
|
+
# iOS will consider the principal urls to be relative to
|
85
|
+
# the current path so it will request a path like this:
|
86
|
+
# /tt/cards/tt/cards/
|
87
|
+
#
|
88
|
+
# if we detect something like this we issue a redirect to
|
89
|
+
# /tt/cards
|
90
|
+
#
|
91
|
+
# after that iOS 6 seems to behave as expected.
|
92
|
+
path = env['REQUEST_PATH'] || env['PATH_INFO']
|
93
|
+
|
94
|
+
parts = path.split('/').reject(&:empty?)
|
95
|
+
|
96
|
+
if parts.size % 2 == 0
|
97
|
+
half1 = parts[0...parts.size / 2]
|
98
|
+
half2 = parts[parts.size / 2..-1]
|
99
|
+
|
100
|
+
if half1 == half2
|
101
|
+
headers = {
|
102
|
+
'Location' => "/#{half1.join('/')}",
|
103
|
+
'Content-Type' => 'text/html',
|
104
|
+
}
|
105
|
+
|
106
|
+
return [301, headers, []]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
[404, {}, []]
|
112
|
+
}
|
74
113
|
end
|
75
114
|
end
|
76
115
|
|
@@ -26,20 +26,14 @@ module DAV4Rack
|
|
26
26
|
# "<D:group-membership-set xmlns:D='DAV:' />"
|
27
27
|
end
|
28
28
|
|
29
|
-
# iOS 6.0 expect "/
|
30
|
-
# UA: iOS/6.0 (10A403) Preferences/1.0
|
31
29
|
property('principal-URL') do
|
32
30
|
<<-EOS
|
33
31
|
<D:principal-URL xmlns:D='DAV:'>
|
34
|
-
<D:href>#{
|
32
|
+
<D:href>#{root_uri_path}</D:href>
|
35
33
|
</D:principal-URL>
|
36
34
|
EOS
|
37
35
|
end
|
38
36
|
|
39
|
-
# This violates the spec that requires an HTTP or HTTPS URL. Unfortunately,
|
40
|
-
# Apple's AddressBook.app treats everything as a pathname. Also, the model
|
41
|
-
# shouldn't need to know about the URL scheme and such.
|
42
|
-
# iOS 6.0 expect /
|
43
37
|
property('current-user-principal') do
|
44
38
|
<<-EOS
|
45
39
|
<D:current-user-principal xmlns:D='DAV:'>
|
@@ -115,13 +109,6 @@ module DAV4Rack
|
|
115
109
|
end
|
116
110
|
|
117
111
|
private
|
118
|
-
def principal_uri
|
119
|
-
if user_agent.start_with?("iOS/6.0")
|
120
|
-
'/'
|
121
|
-
else
|
122
|
-
root_uri_path
|
123
|
-
end
|
124
|
-
end
|
125
112
|
|
126
113
|
def books_collection_url
|
127
114
|
File.join(root_uri_path, options[:books_collection])
|
data/lib/dav4rack_ext/version.rb
CHANGED
data/specs/support/models.rb
CHANGED
@@ -44,10 +44,10 @@ module Testing
|
|
44
44
|
end
|
45
45
|
|
46
46
|
if existing_field
|
47
|
-
puts "Updated '#{a.group}.#{a.name}' to '#{a.value}'"
|
47
|
+
# puts "Updated '#{a.group}.#{a.name}' to '#{a.value}'"
|
48
48
|
existing_field.value = a.value
|
49
49
|
else
|
50
|
-
puts "Created '#{a.group}.#{a.name}' with '#{a.value}'"
|
50
|
+
# puts "Created '#{a.group}.#{a.name}' with '#{a.value}'"
|
51
51
|
fields << Field.from_vcf_field(a)
|
52
52
|
end
|
53
53
|
end
|
@@ -55,8 +55,6 @@ module Testing
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def save
|
58
|
-
p fields
|
59
|
-
|
60
58
|
# no-op
|
61
59
|
true
|
62
60
|
end
|
@@ -26,19 +26,20 @@ describe 'Principal Resource' do
|
|
26
26
|
['principal-URL', @dav_ns]
|
27
27
|
], headers)
|
28
28
|
|
29
|
-
ensure_element_exists(response, %{D|prop > D|principal-URL > D|href[text()="/cards
|
29
|
+
ensure_element_exists(response, %{D|prop > D|principal-URL > D|href[text()="/cards"]})
|
30
30
|
end
|
31
31
|
|
32
|
-
should '
|
32
|
+
should 'handle stupid requests from iOS 6.0' do
|
33
33
|
headers = {
|
34
34
|
'HTTP_USER_AGENT' => 'iOS/6.0 (10A403) Preferences/1.0'
|
35
35
|
}
|
36
36
|
|
37
|
-
response = propfind('/cards/', [
|
37
|
+
response = propfind('/something/cards/something/cards/', [
|
38
38
|
['principal-URL', @dav_ns]
|
39
39
|
], headers)
|
40
40
|
|
41
|
-
|
41
|
+
response.status.should == 301
|
42
|
+
response.headers['Location'].should == '/something/cards'
|
42
43
|
end
|
43
44
|
|
44
45
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dav4rack_ext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: dav4rack
|
@@ -114,7 +114,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
114
114
|
version: '0'
|
115
115
|
segments:
|
116
116
|
- 0
|
117
|
-
hash:
|
117
|
+
hash: -3870677578492079712
|
118
118
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
119
|
none: false
|
120
120
|
requirements:
|
@@ -123,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
123
|
version: '0'
|
124
124
|
segments:
|
125
125
|
- 0
|
126
|
-
hash:
|
126
|
+
hash: -3870677578492079712
|
127
127
|
requirements: []
|
128
128
|
rubyforge_project:
|
129
129
|
rubygems_version: 1.8.23
|