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 CHANGED
@@ -13,7 +13,7 @@ group(:example) do
13
13
  end
14
14
 
15
15
  group(:test) do
16
- gem 'eetee', '= 0.0.1'
16
+ gem 'eetee', '~> 0.0.1'
17
17
  gem 'mocha', '~> 0.12.0'
18
18
  gem 'factory_girl', '~> 4.0'
19
19
  gem 'virtus'
data/example/config.ru CHANGED
@@ -40,7 +40,7 @@ app2 = DAV4Rack::Carddav.app('/:prefix/cards/',
40
40
  current_user: method(:create_user),
41
41
  root_uri_path: lambda do |env|
42
42
  path = env['REQUEST_PATH']
43
- n = path.index("/cards/")
43
+ n = path.index("/cards")
44
44
  path[0...(n + 7)]
45
45
  end
46
46
  )
@@ -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
- # try to help iOS
21
- r.add("#{root_path}/.well_known/carddav/").to do |env|
22
- root = env['REQUEST_PATH']
23
- pos = root.index('.well_known')
24
- [302, {'Location' => root[0...pos]}, []]
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>#{principal_uri}</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])
@@ -1,3 +1,3 @@
1
1
  module Dav4rackExt
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -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 'return / as principal-URI for iOS 6.0' do
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
- ensure_element_exists(response, %{D|prop > D|principal-URL > D|href[text()="/"]})
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.2
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-11-30 00:00:00.000000000 Z
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: 29217618825468100
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: 29217618825468100
126
+ hash: -3870677578492079712
127
127
  requirements: []
128
128
  rubyforge_project:
129
129
  rubygems_version: 1.8.23