6
6
7
7
package at.bitfire.dav4jvm
8
8
9
+ import at.bitfire.dav4jvm.UrlUtils.omitTrailingSlash
10
+ import at.bitfire.dav4jvm.UrlUtils.withTrailingSlash
9
11
import okhttp3.HttpUrl
10
- import java.net.URI
11
- import java.net.URISyntaxException
12
- import java.util.logging.Level
13
- import java.util.logging.Logger
14
12
15
13
object UrlUtils {
16
14
17
- private val logger
18
- get() = Logger .getLogger(javaClass.name)
19
-
20
-
21
- /* *
22
- * Compares two URLs in WebDAV context. If two URLs are considered *equal*, both
23
- * represent the same WebDAV resource (e.g. `http://host:80/folder1` and `http://HOST/folder1#somefragment`).
24
- *
25
- * It decodes %xx entities in the path, so `/my@dav` and `/my%40dav` are considered the same.
26
- * This is important to process multi-status responses: some servers serve a multi-status
27
- * response with href `/my@dav` when you request `/my%40dav` and vice versa.
28
- *
29
- * This method does not deal with trailing slashes, so if you want to compare collection URLs,
30
- * make sure they both (don't) have a trailing slash before calling this method, for instance
31
- * with [omitTrailingSlash] or [withTrailingSlash].
32
- *
33
- * @param url1 the first URL to be compared
34
- * @param url2 the second URL to be compared
35
- *
36
- * @return whether [url1] and [url2] (usually) represent the same WebDAV resource
37
- */
38
- fun equals (url1 : HttpUrl , url2 : HttpUrl ): Boolean {
39
- // if okhttp thinks the two URLs are equal, they're in any case
40
- // (and it's a simple String comparison)
41
- if (url1 == url2)
42
- return true
43
-
44
- // convert to java.net.URI (also corrects some mistakes)
45
- val uri1 = url1.toUri()
46
- val uri2 = url2.toUri()
47
-
48
- // if the URIs are the same (ignoring scheme case and fragments), they're equal for us
49
- if (uri1.scheme.equals(uri2.scheme, true ) && uri1.schemeSpecificPart == uri2.schemeSpecificPart)
50
- return true
51
-
52
- return try {
53
- val decoded1 = URI (url1.scheme, uri1.schemeSpecificPart, null )
54
- val decoded2 = URI (uri2.scheme, uri2.schemeSpecificPart, null )
55
- decoded1 == decoded2
56
- } catch (e: URISyntaxException ) {
57
- logger.log(Level .WARNING , " Couldn't decode URI for comparison, assuming inequality" , e)
58
- false
59
- }
60
- }
15
+ @Deprecated(" Use equalsForWebDAV instead" , ReplaceWith (" url1.equalsForWebDAV(url2)" ))
16
+ fun equals (url1 : HttpUrl , url2 : HttpUrl ) = url1.equalsForWebDAV(url2)
61
17
62
18
/* *
63
19
* Gets the first-level domain name (without subdomains) from a host name.
@@ -117,4 +73,37 @@ object UrlUtils {
117
73
url.newBuilder().addPathSegment(" " ).build()
118
74
}
119
75
76
+ }
77
+
78
+ /* *
79
+ * Compares two [HttpUrl]s in WebDAV context. If two URLs are considered *equal*, both
80
+ * represent the same WebDAV resource.
81
+ *
82
+ * The fragment of an URL is ignored, e.g. `http://host:80/folder1` and `http://HOST/folder1#somefragment`
83
+ * are considered to be equal.
84
+ *
85
+ * [HttpUrl] is less strict than [java.net.URI] and allows for instance (not encoded) square brackets in the path.
86
+ * So this method tries to normalize the URI by converting it to a [java.net.URI] (encodes for instance square brackets)
87
+ * and then comparing the scheme and scheme-specific part (without fragment).
88
+ *
89
+ * Attention: **This method does not deal with trailing slashes**, so if you want to compare collection URLs,
90
+ * make sure they both (don't) have a trailing slash before calling this method, for instance
91
+ * with [omitTrailingSlash] or [withTrailingSlash].
92
+ *
93
+ * @param other the URL to compare the current object with
94
+ *
95
+ * @return whether the URLs are considered to represent the same WebDAV resource
96
+ */
97
+ fun HttpUrl.equalsForWebDAV (other : HttpUrl ): Boolean {
98
+ // if okhttp thinks the two URLs are equal, they're in any case
99
+ // (and it's a simple String comparison)
100
+ if (this == other)
101
+ return true
102
+
103
+ // convert to java.net.URI (also corrects some mistakes and escapes for instance square brackets)
104
+ val uri1 = toUri()
105
+ val uri2 = other.toUri()
106
+
107
+ // if the URIs are the same (ignoring scheme case and fragments), they're equal for us
108
+ return uri1.scheme.equals(uri2.scheme, true ) && uri1.schemeSpecificPart == uri2.schemeSpecificPart
120
109
}
0 commit comments