dav4rack_ext 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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