golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/webdav/if_test.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package webdav 6 7 import ( 8 "reflect" 9 "strings" 10 "testing" 11 ) 12 13 func TestParseIfHeader(t *testing.T) { 14 // The "section x.y.z" test cases come from section x.y.z of the spec at 15 // http://www.webdav.org/specs/rfc4918.html 16 testCases := []struct { 17 desc string 18 input string 19 want ifHeader 20 }{{ 21 "bad: empty", 22 ``, 23 ifHeader{}, 24 }, { 25 "bad: no parens", 26 `foobar`, 27 ifHeader{}, 28 }, { 29 "bad: empty list #1", 30 `()`, 31 ifHeader{}, 32 }, { 33 "bad: empty list #2", 34 `(a) (b c) () (d)`, 35 ifHeader{}, 36 }, { 37 "bad: no list after resource #1", 38 `<foo>`, 39 ifHeader{}, 40 }, { 41 "bad: no list after resource #2", 42 `<foo> <bar> (a)`, 43 ifHeader{}, 44 }, { 45 "bad: no list after resource #3", 46 `<foo> (a) (b) <bar>`, 47 ifHeader{}, 48 }, { 49 "bad: no-tag-list followed by tagged-list", 50 `(a) (b) <foo> (c)`, 51 ifHeader{}, 52 }, { 53 "bad: unfinished list", 54 `(a`, 55 ifHeader{}, 56 }, { 57 "bad: unfinished ETag", 58 `([b`, 59 ifHeader{}, 60 }, { 61 "bad: unfinished Notted list", 62 `(Not a`, 63 ifHeader{}, 64 }, { 65 "bad: double Not", 66 `(Not Not a)`, 67 ifHeader{}, 68 }, { 69 "good: one list with a Token", 70 `(a)`, 71 ifHeader{ 72 lists: []ifList{{ 73 conditions: []Condition{{ 74 Token: `a`, 75 }}, 76 }}, 77 }, 78 }, { 79 "good: one list with an ETag", 80 `([a])`, 81 ifHeader{ 82 lists: []ifList{{ 83 conditions: []Condition{{ 84 ETag: `a`, 85 }}, 86 }}, 87 }, 88 }, { 89 "good: one list with three Nots", 90 `(Not a Not b Not [d])`, 91 ifHeader{ 92 lists: []ifList{{ 93 conditions: []Condition{{ 94 Not: true, 95 Token: `a`, 96 }, { 97 Not: true, 98 Token: `b`, 99 }, { 100 Not: true, 101 ETag: `d`, 102 }}, 103 }}, 104 }, 105 }, { 106 "good: two lists", 107 `(a) (b)`, 108 ifHeader{ 109 lists: []ifList{{ 110 conditions: []Condition{{ 111 Token: `a`, 112 }}, 113 }, { 114 conditions: []Condition{{ 115 Token: `b`, 116 }}, 117 }}, 118 }, 119 }, { 120 "good: two Notted lists", 121 `(Not a) (Not b)`, 122 ifHeader{ 123 lists: []ifList{{ 124 conditions: []Condition{{ 125 Not: true, 126 Token: `a`, 127 }}, 128 }, { 129 conditions: []Condition{{ 130 Not: true, 131 Token: `b`, 132 }}, 133 }}, 134 }, 135 }, { 136 "section 7.5.1", 137 `<http://www.example.com/users/f/fielding/index.html> 138 (<urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6>)`, 139 ifHeader{ 140 lists: []ifList{{ 141 resourceTag: `http://www.example.com/users/f/fielding/index.html`, 142 conditions: []Condition{{ 143 Token: `urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6`, 144 }}, 145 }}, 146 }, 147 }, { 148 "section 7.5.2 #1", 149 `(<urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf>)`, 150 ifHeader{ 151 lists: []ifList{{ 152 conditions: []Condition{{ 153 Token: `urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf`, 154 }}, 155 }}, 156 }, 157 }, { 158 "section 7.5.2 #2", 159 `<http://example.com/locked/> 160 (<urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf>)`, 161 ifHeader{ 162 lists: []ifList{{ 163 resourceTag: `http://example.com/locked/`, 164 conditions: []Condition{{ 165 Token: `urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf`, 166 }}, 167 }}, 168 }, 169 }, { 170 "section 7.5.2 #3", 171 `<http://example.com/locked/member> 172 (<urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf>)`, 173 ifHeader{ 174 lists: []ifList{{ 175 resourceTag: `http://example.com/locked/member`, 176 conditions: []Condition{{ 177 Token: `urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf`, 178 }}, 179 }}, 180 }, 181 }, { 182 "section 9.9.6", 183 `(<urn:uuid:fe184f2e-6eec-41d0-c765-01adc56e6bb4>) 184 (<urn:uuid:e454f3f3-acdc-452a-56c7-00a5c91e4b77>)`, 185 ifHeader{ 186 lists: []ifList{{ 187 conditions: []Condition{{ 188 Token: `urn:uuid:fe184f2e-6eec-41d0-c765-01adc56e6bb4`, 189 }}, 190 }, { 191 conditions: []Condition{{ 192 Token: `urn:uuid:e454f3f3-acdc-452a-56c7-00a5c91e4b77`, 193 }}, 194 }}, 195 }, 196 }, { 197 "section 9.10.8", 198 `(<urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4>)`, 199 ifHeader{ 200 lists: []ifList{{ 201 conditions: []Condition{{ 202 Token: `urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4`, 203 }}, 204 }}, 205 }, 206 }, { 207 "section 10.4.6", 208 `(<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2> 209 ["I am an ETag"]) 210 (["I am another ETag"])`, 211 ifHeader{ 212 lists: []ifList{{ 213 conditions: []Condition{{ 214 Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`, 215 }, { 216 ETag: `"I am an ETag"`, 217 }}, 218 }, { 219 conditions: []Condition{{ 220 ETag: `"I am another ETag"`, 221 }}, 222 }}, 223 }, 224 }, { 225 "section 10.4.7", 226 `(Not <urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2> 227 <urn:uuid:58f202ac-22cf-11d1-b12d-002035b29092>)`, 228 ifHeader{ 229 lists: []ifList{{ 230 conditions: []Condition{{ 231 Not: true, 232 Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`, 233 }, { 234 Token: `urn:uuid:58f202ac-22cf-11d1-b12d-002035b29092`, 235 }}, 236 }}, 237 }, 238 }, { 239 "section 10.4.8", 240 `(<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>) 241 (Not <DAV:no-lock>)`, 242 ifHeader{ 243 lists: []ifList{{ 244 conditions: []Condition{{ 245 Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`, 246 }}, 247 }, { 248 conditions: []Condition{{ 249 Not: true, 250 Token: `DAV:no-lock`, 251 }}, 252 }}, 253 }, 254 }, { 255 "section 10.4.9", 256 `</resource1> 257 (<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2> 258 [W/"A weak ETag"]) (["strong ETag"])`, 259 ifHeader{ 260 lists: []ifList{{ 261 resourceTag: `/resource1`, 262 conditions: []Condition{{ 263 Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`, 264 }, { 265 ETag: `W/"A weak ETag"`, 266 }}, 267 }, { 268 resourceTag: `/resource1`, 269 conditions: []Condition{{ 270 ETag: `"strong ETag"`, 271 }}, 272 }}, 273 }, 274 }, { 275 "section 10.4.10", 276 `<http://www.example.com/specs/> 277 (<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>)`, 278 ifHeader{ 279 lists: []ifList{{ 280 resourceTag: `http://www.example.com/specs/`, 281 conditions: []Condition{{ 282 Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`, 283 }}, 284 }}, 285 }, 286 }, { 287 "section 10.4.11 #1", 288 `</specs/rfc2518.doc> (["4217"])`, 289 ifHeader{ 290 lists: []ifList{{ 291 resourceTag: `/specs/rfc2518.doc`, 292 conditions: []Condition{{ 293 ETag: `"4217"`, 294 }}, 295 }}, 296 }, 297 }, { 298 "section 10.4.11 #2", 299 `</specs/rfc2518.doc> (Not ["4217"])`, 300 ifHeader{ 301 lists: []ifList{{ 302 resourceTag: `/specs/rfc2518.doc`, 303 conditions: []Condition{{ 304 Not: true, 305 ETag: `"4217"`, 306 }}, 307 }}, 308 }, 309 }} 310 311 for _, tc := range testCases { 312 got, ok := parseIfHeader(strings.Replace(tc.input, "\n", "", -1)) 313 if gotEmpty := reflect.DeepEqual(got, ifHeader{}); gotEmpty == ok { 314 t.Errorf("%s: should be different: empty header == %t, ok == %t", tc.desc, gotEmpty, ok) 315 continue 316 } 317 if !reflect.DeepEqual(got, tc.want) { 318 t.Errorf("%s:\ngot %v\nwant %v", tc.desc, got, tc.want) 319 continue 320 } 321 } 322 }