1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "testutils.h"
34
35 #include "../webdav/requestparser.h"
36 #include "../webdav/webdav.h"
37 #include "../webdav/multistatus.h"
38 #include "../webdav/operation.h"
39
40 #include "vfs.h"
41 #include "webdav.h"
42
43 static int webdav_is_initialized =
0;
44
45
46
47 static int backend2_init_called =
0;
48 static int backend2_propfind_do_count =
0;
49 static int backend2_propfind_finish_called =
0;
50 static int backend2_proppatch_commit =
0;
51 static int backend2_proppatch_do_count =
0;
52 static int backend2_proppatch_finish_count =
0;
53
54
55 static int backend2_propfind_init(
56 WebdavPropfindRequest *propfind,
57 const char *path,
58 const char *href,
59 WebdavPList **outPList)
60 {
61 backend2_init_called =
1;
62 return 0;
63 }
64
65 static int backend2_propfind_do(
66 WebdavPropfindRequest *propfind,
67 WebdavResponse *response,
68 VFS_DIR parent,
69 WebdavResource *resource,
70 struct stat *s)
71 {
72 backend2_propfind_do_count++;
73 return 0;
74 }
75
76 static int backend2_propfind_finish(WebdavPropfindRequest *propfind) {
77 backend2_propfind_finish_called =
1;
78 return 0;
79 }
80
81 static int backend2_proppatch_do(
82 WebdavProppatchRequest *request,
83 WebdavResource *response,
84 VFSFile *file,
85 WebdavPList **out_set,
86 WebdavPList **out_remove)
87 {
88 backend2_proppatch_do_count++;
89
90 if(*out_remove) {
91 return 1;
92 }
93
94 WebdavPListIterator i = webdav_plist_iterator(out_set);
95 WebdavPList *cur;
96 while(webdav_plist_iterator_next(&i, &cur)) {
97 if(!strcmp(cur->property->name,
"a")) {
98
99 return 1;
100 }
else if(!strcmp(cur->property->name,
"abort")) {
101 return 1;
102 }
103 response->addproperty(response, cur->property,
200);
104 webdav_plist_iterator_remove_current(&i);
105 }
106
107 return 0;
108 }
109
110 static int backend2_proppatch_finish(
111 WebdavProppatchRequest *request,
112 WebdavResource *response,
113 VFSFile *file,
114 WSBool commit)
115 {
116 backend2_proppatch_finish_count++;
117 backend2_proppatch_commit = commit;
118 return 0;
119 }
120
121 static WebdavBackend backend2 = {
122 backend2_propfind_init,
123 backend2_propfind_do,
124 backend2_propfind_finish,
125 backend2_proppatch_do,
126 backend2_proppatch_finish,
127 NULL,
128 NULL,
129 NULL,
130 NULL,
131 0,
132 NULL,
133 NULL
134 };
135
136
137
138 static int backend1_init_called =
0;
139 static int backend1_propfind_do_count =
0;
140 static int backend1_propfind_finish_called =
0;
141 static int backend1_proppatch_commit =
0;
142 static int backend1_proppatch_do_count =
0;
143 static int backend1_proppatch_finish_count =
0;
144
145
146 static int backend1_propfind_init(
147 WebdavPropfindRequest *propfind,
148 const char *path,
149 const char *href,
150 WebdavPList **outPList)
151 {
152 backend1_init_called =
1;
153
154 WebdavPList *plist = *outPList;
155 WebdavProperty *p = plist->property;
156 if(!strcmp(p->name,
"displayname")) {
157 plist->next->prev =
NULL;
158 *outPList = plist->next;
159 }
else {
160 return 1;
161 }
162
163 return 0;
164 }
165
166 static int backend1_propfind_do(
167 WebdavPropfindRequest *propfind,
168 WebdavResponse *response,
169 VFS_DIR parent,
170 WebdavResource *resource,
171 struct stat *s)
172 {
173 backend1_propfind_do_count++;
174 return 0;
175 }
176
177 static int backend1_propfind_finish(WebdavPropfindRequest *propfind) {
178 backend1_propfind_finish_called =
1;
179 return 0;
180 }
181
182 static int backend1_proppatch_do(
183 WebdavProppatchRequest *request,
184 WebdavResource *response,
185 VFSFile *file,
186 WebdavPList **out_set,
187 WebdavPList **out_remove)
188 {
189 backend1_proppatch_do_count++;
190
191
192 WebdavPListIterator i = webdav_plist_iterator(out_remove);
193 WebdavPList *cur;
194 while(webdav_plist_iterator_next(&i, &cur)) {
195 response->addproperty(response, cur->property,
200);
196 webdav_plist_iterator_remove_current(&i);
197 }
198
199
200 i = webdav_plist_iterator(out_set);
201 while(webdav_plist_iterator_next(&i, &cur)) {
202 if(!strcmp(cur->property->name,
"fail")) {
203 response->addproperty(response, cur->property,
403);
204 webdav_plist_iterator_remove_current(&i);
205 }
else if(!strcmp(cur->property->name,
"a")) {
206 response->addproperty(response, cur->property,
200);
207 webdav_plist_iterator_remove_current(&i);
208 }
209 }
210
211 return 0;
212 }
213
214 static int backend1_proppatch_finish(
215 WebdavProppatchRequest *request,
216 WebdavResource *response,
217 VFSFile *file,
218 WSBool commit)
219 {
220 backend1_proppatch_finish_count++;
221 backend1_proppatch_commit = commit;
222 return 0;
223 }
224
225 WebdavBackend backend1 = {
226 backend1_propfind_init,
227 backend1_propfind_do,
228 backend1_propfind_finish,
229 backend1_proppatch_do,
230 backend1_proppatch_finish,
231 NULL,
232 NULL,
233 NULL,
234 NULL,
235 0,
236 NULL,
237 &backend2
238 };
239
240 static void reset_backends(
void) {
241 backend1_init_called =
0;
242 backend1_propfind_do_count =
0;
243 backend1_propfind_finish_called =
0;
244 backend1_proppatch_commit =
0;
245 backend1_proppatch_do_count =
0;
246 backend1_proppatch_finish_count =
0;
247 backend2_init_called =
0;
248 backend2_propfind_do_count =
0;
249 backend2_propfind_finish_called =
0;
250 backend2_proppatch_commit =
0;
251 backend2_proppatch_do_count =
0;
252 backend2_proppatch_finish_count =
0;
253 }
254
255
256
257
258 static int test_init(
259 Session **out_sn,
260 Request **out_rq,
261 WebdavPropfindRequest **out_propfind,
262 const char *xml)
263 {
264 if(!webdav_is_initialized) {
265 if(webdav_init(
NULL,
NULL,
NULL) !=
REQ_PROCEED) {
266 return 1;
267 }
268 webdav_is_initialized =
1;
269 }
270
271 Session *sn = testutil_session();
272 Request *rq = testutil_request(sn->pool,
"PROPFIND",
"/");
273
274 int error =
0;
275
276 WebdavPropfindRequest *propfind = propfind_parse(
277 sn,
278 rq,
279 xml,
280 strlen(xml),
281 &error);
282
283 if(error) {
284 return 1;
285 }
286
287 if(!propfind || !propfind->properties) {
288 return 1;
289 }
290
291 *out_sn = sn;
292 *out_rq = rq;
293 *out_propfind = propfind;
294 return 0;
295 }
296
297 static WebdavOperation* test_propfind_op(
298 Session **out_sn,
299 Request **out_rq,
300 const char *xml)
301 {
302 WebdavPropfindRequest *propfind;
303 if(test_init(out_sn, out_rq, &propfind, xml)) {
304 return NULL;
305 }
306
307 Multistatus *ms = multistatus_response(*out_sn, *out_rq);
308 if(!ms) {
309 return NULL;
310 }
311
312
313 WebdavResponse *response = (WebdavResponse*)ms;
314
315 WebdavPropfindRequestList *requests =
NULL;
316
317
318 if(webdav_propfind_init(&backend1, propfind,
"/",
"/", &requests)) {
319 return NULL;
320 }
321
322 return webdav_create_propfind_operation(
323 (*out_sn),
324 (*out_rq),
325 &backend1,
326 propfind->properties,
327 requests,
328 response);
329 }
330
331
332 UCX_TEST(test_webdav_plist_add) {
333 Session *sn = testutil_session();
334
335 UCX_TEST_BEGIN;
336
337 WebdavPList *begin =
NULL;
338 WebdavPList *end =
NULL;
339
340 WebdavProperty p1, p2, p3;
341 ZERO(&p1,
sizeof(WebdavProperty));
342 ZERO(&p2,
sizeof(WebdavProperty));
343 ZERO(&p3,
sizeof(WebdavProperty));
344 int r;
345
346 r = webdav_plist_add(sn->pool, &begin, &end, &p1);
347
348 UCX_TEST_ASSERT(r ==
0,
"add 1 failed");
349 UCX_TEST_ASSERT(begin && end,
"ptrs are NULL");
350 UCX_TEST_ASSERT(begin == end,
"begin != end");
351 UCX_TEST_ASSERT(begin->prev ==
NULL,
"begin->prev not NULL");
352 UCX_TEST_ASSERT(begin->next ==
NULL,
"begin->next not NULL");
353
354 r = webdav_plist_add(sn->pool, &begin, &end, &p2);
355
356 UCX_TEST_ASSERT(r ==
0,
"add 2 failed");
357 UCX_TEST_ASSERT(begin && end,
"add2: ptrs are NULL");
358 UCX_TEST_ASSERT(begin->next,
"begin->next is NULL");
359 UCX_TEST_ASSERT(begin->next == end,
"begin->next != end");
360 UCX_TEST_ASSERT(end->prev = begin,
"end->prev != begin");
361 UCX_TEST_ASSERT(begin->prev ==
NULL,
"add2: begin->prev not NULL");
362 UCX_TEST_ASSERT(end->next ==
NULL,
"add2: end->next not NULL");
363
364 r = webdav_plist_add(sn->pool, &begin, &end, &p3);
365
366 UCX_TEST_ASSERT(r ==
0,
"add 3 failed");
367 UCX_TEST_ASSERT(begin && end,
"add3: ptrs are NULL");
368 UCX_TEST_ASSERT(begin->next == end->prev,
"begin->next != end->prev");
369
370 UCX_TEST_END;
371
372 testutil_destroy_session(sn);
373 }
374
375 UCX_TEST(test_webdav_plist_size) {
376 Session *sn = testutil_session();
377
378 UCX_TEST_BEGIN;
379
380 WebdavPList *begin =
NULL;
381 WebdavPList *end =
NULL;
382
383 WebdavProperty p1, p2, p3;
384 ZERO(&p1,
sizeof(WebdavProperty));
385 ZERO(&p2,
sizeof(WebdavProperty));
386 ZERO(&p3,
sizeof(WebdavProperty));
387 int r;
388
389 UCX_TEST_ASSERT(webdav_plist_size(begin) ==
0,
"size != 0");
390 r = webdav_plist_add(sn->pool, &begin, &end, &p1);
391 UCX_TEST_ASSERT(webdav_plist_size(begin) ==
1,
"size != 1");
392 r = webdav_plist_add(sn->pool, &begin, &end, &p2);
393 UCX_TEST_ASSERT(webdav_plist_size(begin) ==
2,
"size != 2");
394 r = webdav_plist_add(sn->pool, &begin, &end, &p3);
395 UCX_TEST_ASSERT(webdav_plist_size(begin) ==
3,
"size != 3");
396
397 UCX_TEST_END;
398
399 testutil_destroy_session(sn);
400 }
401
402 UCX_TEST(test_propfind_parse) {
403 Session *sn = testutil_session();
404 Request *rq = testutil_request(sn->pool,
"PROPFIND",
"/");
405
406 UCX_TEST_BEGIN
407
408 int error =
0;
409
410
411
412
413 WebdavPropfindRequest *p1 = propfind_parse(
414 sn,
415 rq,
416 TEST_PROPFIND1,
417 strlen(
TEST_PROPFIND1),
418 &error);
419
420 UCX_TEST_ASSERT(p1,
"p1 is NULL");
421 UCX_TEST_ASSERT(p1->properties,
"p1: no props");
422 UCX_TEST_ASSERT(!p1->allprop,
"p1: allprop is TRUE");
423 UCX_TEST_ASSERT(!p1->propname,
"p1: propname is TRUE");
424 UCX_TEST_ASSERT(p1->propcount ==
6,
"p1: wrong propcount");
425
426
427 WebdavPList *elm = p1->properties;
428 UCX_TEST_ASSERT(
429 !strcmp(elm->property->name,
"displayname"),
430 "p1: property 1 has wrong name");
431 UCX_TEST_ASSERT(
432 !strcmp((
char*)elm->property->namespace->href,
"DAV:"),
433 "p1: property 1 has wrong namespace");
434
435
436 elm = elm->next;
437 UCX_TEST_ASSERT(elm,
"p1: property 2 missing");
438 UCX_TEST_ASSERT(
439 !strcmp(elm->property->name,
"getcontentlength"),
440 "p1: property 2 has wrong name");
441 UCX_TEST_ASSERT(
442 !strcmp((
char*)elm->property->namespace->href,
"DAV:"),
443 "p1: property 2 has wrong namespace");
444
445 elm = elm->next;
446 UCX_TEST_ASSERT(elm,
"p1: property 3 missing");
447 elm = elm->next;
448 UCX_TEST_ASSERT(elm,
"p1: property 4 missing");
449 elm = elm->next;
450 UCX_TEST_ASSERT(elm,
"p1: property 5 missing");
451
452
453 elm = elm->next;
454 UCX_TEST_ASSERT(elm,
"p1: property 6 missing");
455 UCX_TEST_ASSERT(
456 !strcmp(elm->property->name,
"getetag"),
457 "p1: property 6 has wrong name");
458 UCX_TEST_ASSERT(
459 !strcmp((
char*)elm->property->namespace->href,
"DAV:"),
460 "p1: property 6 has wrong namespace");
461 UCX_TEST_ASSERT(!elm->next,
"p1: should not have property 7");
462
463
464
465
466 WebdavPropfindRequest *p2 = propfind_parse(
467 sn,
468 rq,
469 TEST_PROPFIND2,
470 strlen(
TEST_PROPFIND2),
471 &error);
472
473 UCX_TEST_ASSERT(p2,
"p2 is NULL");
474 UCX_TEST_ASSERT(p2->properties,
"p2: no props");
475 UCX_TEST_ASSERT(!p2->allprop,
"p2: allprop is TRUE");
476 UCX_TEST_ASSERT(!p2->propname,
"p2: propname is TRUE");
477
478
479 elm = p2->properties;
480 UCX_TEST_ASSERT(
481 !strcmp(elm->property->name,
"resourcetype"),
482 "p2: property 1 has wrong name");
483 UCX_TEST_ASSERT(
484 !strcmp((
char*)elm->property->namespace->href,
"DAV:"),
485 "p2: property 1 has wrong namespace");
486
487
488 elm = elm->next;
489 UCX_TEST_ASSERT(elm,
"p2: property 2 missing");
490 UCX_TEST_ASSERT(
491 !strcmp(elm->property->name,
"testprop"),
492 "p2: property 2 has wrong name");
493 UCX_TEST_ASSERT(
494 !strcmp((
char*)elm->property->namespace->href,
"http://example.com/"),
495 "p2: property 2 has wrong namespace");
496
497
498 elm = elm->next;
499 UCX_TEST_ASSERT(elm,
"p2: property 3 missing");
500 UCX_TEST_ASSERT(
501 !strcmp(elm->property->name,
"name"),
502 "p2: property 3 has wrong name");
503 UCX_TEST_ASSERT(
504 !strcmp((
char*)elm->property->namespace->href,
"http://example.com/"),
505 "p2: property 3 has wrong namespace");
506
507
508 elm = elm->next;
509 UCX_TEST_ASSERT(elm,
"p2: property 4 missing");
510 UCX_TEST_ASSERT(
511 !strcmp(elm->property->name,
"testprop"),
512 "p2: property 4 has wrong name");
513 UCX_TEST_ASSERT(
514 !strcmp((
char*)elm->property->namespace->href,
"testns"),
515 "p2: property 4 has wrong namespace");
516
517
518
519
520
521 WebdavPropfindRequest *p3 = propfind_parse(sn, rq,
TEST_PROPFIND3, strlen(
TEST_PROPFIND3), &error);
522
523 UCX_TEST_ASSERT(p3,
"p3 is NULL");
524 UCX_TEST_ASSERT(!p3->properties,
"p2: has props");
525 UCX_TEST_ASSERT(p3->allprop,
"p2: allprop is FALSE");
526 UCX_TEST_ASSERT(!p3->propname,
"p2: propname is TRUE");
527 UCX_TEST_ASSERT(p3->propcount ==
0,
"p2: wrong propcount");
528
529
530
531
532
533 WebdavPropfindRequest *p4 = propfind_parse(sn, rq,
TEST_PROPFIND4, strlen(
TEST_PROPFIND4), &error);
534
535 UCX_TEST_ASSERT(p4,
"p4 is NULL");
536 UCX_TEST_ASSERT(!p4->properties,
"p2: has props");
537 UCX_TEST_ASSERT(!p4->allprop,
"p2: allprop is TRUE");
538 UCX_TEST_ASSERT(p4->propname,
"p2: propname is FALSE");
539
540
541
542
543
544 WebdavPropfindRequest *p5 = propfind_parse(sn, rq,
TEST_PROPFIND5, strlen(
TEST_PROPFIND5), &error);
545
546 UCX_TEST_ASSERT(p5,
"p5 is NULL");
547 UCX_TEST_ASSERT(p5->properties,
"p5: no props");
548 UCX_TEST_ASSERT(!p5->allprop,
"p5: allprop is TRUE");
549 UCX_TEST_ASSERT(!p5->propname,
"p5: propname is TRUE");
550 UCX_TEST_ASSERT(p5->propcount ==
4,
"p5: wrong propcount");
551
552
553 elm = p5->properties;
554 UCX_TEST_ASSERT(elm,
"p5: property 1 missing");
555 UCX_TEST_ASSERT(
556 !strcmp(elm->property->name,
"displayname"),
557 "p5: property 1 has wrong name");
558 UCX_TEST_ASSERT(
559 !strcmp((
char*)elm->property->namespace->href,
"DAV:"),
560 "p5: property 1 has wrong namespace");
561
562 elm = elm->next;
563 UCX_TEST_ASSERT(elm,
"p5: property 2 missing");
564 elm = elm->next;
565 UCX_TEST_ASSERT(elm,
"p5: property 3 missing");
566
567
568 elm = elm->next;
569 UCX_TEST_ASSERT(elm,
"p5: property 4 missing");
570 UCX_TEST_ASSERT(
571 !strcmp(elm->property->name,
"resourcetype"),
572 "p5: property 4 has wrong name");
573 UCX_TEST_ASSERT(
574 !strcmp((
char*)elm->property->namespace->href,
"DAV:"),
575 "p5: property 4 has wrong namespace");
576
577
578
579
580
581 WebdavPropfindRequest *p6 = propfind_parse(sn, rq,
TEST_PROPFIND6, strlen(
TEST_PROPFIND6), &error);
582
583 UCX_TEST_ASSERT(p6,
"p5 is NULL");
584 UCX_TEST_ASSERT(!p6->properties,
"p5: has props");
585 UCX_TEST_ASSERT(p6->allprop,
"p5: allprop is FALSE");
586 UCX_TEST_ASSERT(!p6->propname,
"p5: propname is TRUE");
587 UCX_TEST_ASSERT(p6->propcount ==
0,
"p5: wrong propcount");
588
589 UCX_TEST_END
590
591 pool_destroy(sn->pool);
592 }
593
594 UCX_TEST(test_proppatch_parse) {
595 Session *sn = testutil_session();
596 Request *rq = testutil_request(sn->pool,
"PROPPATCH",
"/");
597
598 UCX_TEST_BEGIN
599 int error =
0;
600
601 WebdavProppatchRequest *p1 = proppatch_parse(sn, rq,
TEST_PROPPATCH1, strlen(
TEST_PROPPATCH1), &error);
602
603 UCX_TEST_ASSERT(p1->set,
"p1: missing set props");
604 UCX_TEST_ASSERT(!p1->remove,
"p1: has remove props");
605 UCX_TEST_ASSERT(p1->setcount ==
2,
"p1: wrong setcount");
606 UCX_TEST_ASSERT(p1->set->next,
"p1: set plist broken");
607 UCX_TEST_ASSERT(!p1->set->next->next,
"p1: set plist has no end");
608 UCX_TEST_ASSERT(p1->set->property,
"p1: missing property ptr in plist");
609 UCX_TEST_ASSERT(
610 !strcmp(p1->set->property->name,
"test"),
611 "p1: wrong property 1 name");
612
613 WebdavProppatchRequest *p2 = proppatch_parse(sn, rq,
TEST_PROPPATCH2, strlen(
TEST_PROPPATCH2), &error);
614
615 UCX_TEST_ASSERT(p2->set,
"p2: missing set props");
616 UCX_TEST_ASSERT(p2->remove,
"p2: missing remove props");
617 UCX_TEST_ASSERT(p2->setcount ==
4,
"p2: wrong setcount");
618 UCX_TEST_ASSERT(p2->removecount ==
1,
"p2: wrong removecount");
619
620 UCX_TEST_ASSERT(
621 !strcmp((
char*)p2->set->property->namespace->href,
"http://example.com/"),
622 "p2: set property 1: wrong namespace");
623 UCX_TEST_ASSERT(
624 !strcmp(p2->set->property->name,
"a"),
625 "p2: set property 1: wrong name");
626 WSXmlNode *p2set1 = p2->set->property->value.node;
627 UCX_TEST_ASSERT(
628 p2set1->type ==
WS_NODE_TEXT,
629 "p2: set property 1: wrong type");
630 UCX_TEST_ASSERT(
631 p2set1->content,
632 "p2: set property 1: no text");
633 UCX_TEST_ASSERT(
634 !strcmp((
char*)p2set1->content,
"test"),
635 "p2: set property 1: wrong value");
636
637 WSXmlNode *p2set3 = p2->set->next->next->property->value.node;
638 UCX_TEST_ASSERT(p2set3,
"p2: set property 3 missing");
639 UCX_TEST_ASSERT(
640 p2set3->type ==
WS_NODE_TEXT,
641 "p2: set property 3: wrong type");
642 UCX_TEST_ASSERT(
643 p2set3->next,
644 "p2: set property 3: missing element X:name");
645
646 UCX_TEST_ASSERT(
647 xmlHasProp(p2set3->next,
"test"BAD_CAST),
648 "p2: set property 3: missing attribute ''test''");
649
650 UCX_TEST_ASSERT(
651 xmlHasProp(p2set3->next,
"abc"BAD_CAST),
652 "p2: set property 3: missing attribute ''abc");
653
654 xmlChar *value1 = xmlGetProp(p2set3->next,
"test"BAD_CAST);
655 UCX_TEST_ASSERT(
656 !strcmp((
char*) value1,
"test1"),
657 "p2: set property 3: wrong attribute value 1");
658 xmlFree(value1);
659
660 xmlChar *value2 = xmlGetProp(p2set3->next,
"abc"BAD_CAST);
661 UCX_TEST_ASSERT(
662 !strcmp((
char*) value2,
"def"),
663 "p2: set property 3: wrong attribute value 2");
664 xmlFree(value2);
665
666 UCX_TEST_ASSERT(
667 !strcmp(p2->remove->property->name,
"e"),
668 "p2: wrong remove property");
669
670 UCX_TEST_END
671
672 pool_destroy(sn->pool);
673 }
674
675 UCX_TEST(test_lock_parse) {
676 Session *sn = testutil_session();
677 Request *rq = testutil_request(sn->pool,
"LOCK",
"/");
678
679 UCX_TEST_BEGIN
680 int error =
0;
681
682 WebdavLockRequest *l1 = lock_parse(sn, rq,
TEST_LOCK1, strlen(
TEST_LOCK1), &error);
683
684 UCX_TEST_ASSERT(l1,
"l1 is NULL");
685 UCX_TEST_ASSERT(l1->type ==
WEBDAV_LOCK_WRITE,
"l1: wrong type");
686 UCX_TEST_ASSERT(l1->scope ==
WEBDAV_LOCK_SHARED,
"l1: wrong scope");
687 UCX_TEST_ASSERT(l1->owner,
"l1: owner is NULL");
688 UCX_TEST_ASSERT(!strcmp((
char*)l1->owner->content,
"User"),
"l1: wrong owner");
689
690 UCX_TEST_END
691
692 pool_destroy(sn->pool);
693 }
694
695 UCX_TEST(test_rqbody2buffer) {
696 Session *sn;
697 Request *rq;
698
699 UCX_TEST_BEGIN;
700
701
702 sn = testutil_session();
703 rq = testutil_request(sn->pool,
"PUT",
"/");
704 testutil_request_body(sn, rq,
"Hello World!",
12);
705
706 CxBuffer b1;
707 rqbody2buffer(sn, rq, &b1);
708 UCX_TEST_ASSERT(b1.size ==
12,
"b1: wrong size");
709 UCX_TEST_ASSERT(!memcmp(b1.space,
"Hello World!",
12),
"b1: wrong content");
710
711 cxBufferDestroy(&b1);
712 testutil_destroy_session(sn);
713
714
715
716 size_t len1 =
25000;
717 unsigned char *body1 = malloc(len1);
718 for(
int i=
0;i<len1;i++) {
719 body1[i] = i;
720 }
721 sn = testutil_session();
722 rq = testutil_request(sn->pool,
"PUT",
"/");
723 testutil_request_body(sn, rq, (
char*)body1, len1);
724
725 CxBuffer b2;
726 rqbody2buffer(sn, rq, &b2);
727 UCX_TEST_ASSERT(b2.size == len1,
"b2: wrong size");
728 UCX_TEST_ASSERT(!memcmp(b2.space, body1, len1),
"b2: wrong content");
729
730 cxBufferDestroy(&b2);
731 testutil_destroy_session(sn);
732
733 UCX_TEST_END;
734 }
735
736 UCX_TEST(test_webdav_plist_iterator) {
737 Session *sn;
738 Request *rq;
739 WebdavPropfindRequest *propfind;
740
741 UCX_TEST_BEGIN;
742 UCX_TEST_ASSERT(!test_init(&sn, &rq, &propfind,
TEST_PROPFIND1),
"init failed");
743
744 WebdavPList *properties = propfind->properties;
745 size_t count =
0;
746
747 WebdavPListIterator i = webdav_plist_iterator(&properties);
748 WebdavPList *cur;
749 while(webdav_plist_iterator_next(&i, &cur)) {
750 switch(i.index) {
751 case 0: {
752 UCX_TEST_ASSERT(!strcmp(cur->property->name,
"displayname"),
"wrong property 1");
753 break;
754 }
755 case 1: {
756 UCX_TEST_ASSERT(!strcmp(cur->property->name,
"getcontentlength"),
"wrong property 2");
757 break;
758 }
759 case 2: {
760 UCX_TEST_ASSERT(!strcmp(cur->property->name,
"getcontenttype"),
"wrong property 3");
761 break;
762 }
763 case 3: {
764 UCX_TEST_ASSERT(!strcmp(cur->property->name,
"getlastmodified"),
"wrong property 4");
765 break;
766 }
767 case 4: {
768 UCX_TEST_ASSERT(!strcmp(cur->property->name,
"resourcetype"),
"wrong property 5");
769 break;
770 }
771 case 5: {
772 UCX_TEST_ASSERT(!strcmp(cur->property->name,
"getetag"),
"wrong property 6");
773 break;
774 }
775 }
776 count++;
777 }
778
779 UCX_TEST_ASSERT(count == propfind->propcount,
"wrong count");
780
781
782 UCX_TEST_END;
783 testutil_destroy_session(sn);
784 }
785
786 UCX_TEST(test_webdav_plist_iterator_remove_current) {
787 Session *sn;
788 Request *rq;
789 WebdavPropfindRequest *propfind;
790
791 UCX_TEST_BEGIN;
792 UCX_TEST_ASSERT(!test_init(&sn, &rq, &propfind,
TEST_PROPFIND1),
"init failed");
793
794 WebdavPList *properties1 = webdav_plist_clone(sn->pool, propfind->properties);
795 WebdavPList *properties2 = webdav_plist_clone(sn->pool, propfind->properties);
796 WebdavPList *properties3 = webdav_plist_clone(sn->pool, propfind->properties);
797 WebdavPList *properties4 = webdav_plist_clone(sn->pool, propfind->properties);
798
799 WebdavPListIterator i;
800 WebdavPList *cur;
801
802
803 i = webdav_plist_iterator(&properties1);
804 while(webdav_plist_iterator_next(&i, &cur)) {
805 if(i.index ==
0) {
806 webdav_plist_iterator_remove_current(&i);
807 }
808 }
809
810 UCX_TEST_ASSERT(!properties1->prev,
"test1: prev not cleared");
811 UCX_TEST_ASSERT(!strcmp(properties1->property->name,
"getcontentlength"),
"test1: wrong property");
812 UCX_TEST_ASSERT(!strcmp(properties1->next->property->name,
"getcontenttype"),
"test1: wrong property 2");
813 UCX_TEST_ASSERT(properties1->next->prev == properties1,
"test1: wrong link");
814
815
816 i = webdav_plist_iterator(&properties2);
817 while(webdav_plist_iterator_next(&i, &cur)) {
818 if(i.index ==
1) {
819 webdav_plist_iterator_remove_current(&i);
820 }
821 }
822
823 UCX_TEST_ASSERT(!strcmp(properties2->next->property->name,
"getcontenttype"),
"test2: wrong property");
824 UCX_TEST_ASSERT(properties2->next->prev == properties2,
"test2: wrong link");
825 UCX_TEST_ASSERT(webdav_plist_size(properties2) ==
5,
"test2: wrong size");
826
827
828 i = webdav_plist_iterator(&properties3);
829 while(webdav_plist_iterator_next(&i, &cur)) {
830 if(i.index ==
5) {
831 webdav_plist_iterator_remove_current(&i);
832 }
833 }
834
835 UCX_TEST_ASSERT(webdav_plist_size(properties3) ==
5,
"test3: wrong size");
836 UCX_TEST_ASSERT(!strcmp(properties3->next->next->next->next->property->name,
"resourcetype"),
"test2: wrong property");
837
838
839 i = webdav_plist_iterator(&properties4);
840 while(webdav_plist_iterator_next(&i, &cur)) {
841 webdav_plist_iterator_remove_current(&i);
842 switch(i.index) {
843 case 0: {
844 UCX_TEST_ASSERT(!strcmp(properties4->property->name,
"getcontentlength"),
"test4: wrong property 2");
845 UCX_TEST_ASSERT(properties4->prev ==
NULL,
"test4: prev not NULL (0)");
846 break;
847 }
848 case 1: {
849 UCX_TEST_ASSERT(!strcmp(properties4->property->name,
"getcontenttype"),
"test4: wrong property 3");
850 UCX_TEST_ASSERT(properties4->prev ==
NULL,
"test4: prev not NULL (1)");
851 break;
852 }
853 case 2: {
854 UCX_TEST_ASSERT(!strcmp(properties4->property->name,
"getlastmodified"),
"test4: wrong property 4");
855 UCX_TEST_ASSERT(properties4->prev ==
NULL,
"test4: prev not NULL (2)");
856 break;
857 }
858 case 3: {
859 UCX_TEST_ASSERT(!strcmp(properties4->property->name,
"resourcetype"),
"test4: wrong property 5");
860 UCX_TEST_ASSERT(properties4->prev ==
NULL,
"test4: prev not NULL (3)");
861 break;
862 }
863 case 4: {
864 UCX_TEST_ASSERT(!strcmp(properties4->property->name,
"getetag"),
"test4: wrong property 6");
865 UCX_TEST_ASSERT(properties4->prev ==
NULL,
"test4: prev not NULL (4)");
866 break;
867 }
868 default: {
869 UCX_TEST_ASSERT(i.index <=
5,
"fail");
870 }
871 }
872 }
873
874 UCX_TEST_ASSERT(properties4 ==
NULL,
"test4: list not NULL");
875
876 UCX_TEST_END;
877 testutil_destroy_session(sn);
878 }
879
880 UCX_TEST(test_msresponse_addproperty) {
881 Session *sn;
882 Request *rq;
883
884 UCX_TEST_BEGIN;
885
886 WebdavOperation *op = test_propfind_op(&sn, &rq,
TEST_PROPFIND1);
887 UCX_TEST_ASSERT(op,
"init failed");
888 UCX_TEST_ASSERT(op->response,
"no response");
889
890 Multistatus *ms = (Multistatus*)op->response;
891 MSResponse *r = (MSResponse*)ms->response.addresource((WebdavResponse*)ms,
"/");
892
893 WebdavProperty p1;
894 WebdavProperty p[
16];
895 const char *names[] = {
"a1",
"a2",
"a3",
"a4",
"a5",
"a6",
"a7",
"a8",
"a9"};
896
897 WSNamespace ns1;
898 ZERO(&ns1,
sizeof(WSNamespace));
899 WSNamespace ns2;
900 ZERO(&ns2,
sizeof(WSNamespace));
901 ns1.prefix = (xmlChar*)
"x1";
902 ns1.href = (xmlChar*)
"http://example.com/test/";
903 ns2.prefix = (xmlChar*)
"x2";
904 ns2.href = (xmlChar*)
"http://example.com/test/";
905
906 WebdavProperty dp1;
907 ZERO(&dp1,
sizeof(WebdavProperty));
908 dp1.name =
"dup";
909 dp1.namespace = &ns1;
910 dp1.value.text.str =
"Hello";
911 dp1.value.text.length =
5;
912 dp1.vtype =
WS_VALUE_TEXT;
913
914 WebdavProperty dp2;
915 ZERO(&dp2,
sizeof(WebdavProperty));
916 dp2.name =
"dup";
917 dp2.namespace = &ns1;
918 dp2.value.text.str =
"Hello";
919 dp2.value.text.length =
5;
920 dp2.vtype =
WS_VALUE_TEXT;
921
922 WebdavProperty dp3;
923 ZERO(&dp3,
sizeof(WebdavProperty));
924 dp3.name =
"dup";
925 dp3.namespace = &ns2;
926 dp3.value.text.str =
"Hello";
927 dp3.value.text.length =
5;
928 dp3.vtype =
WS_VALUE_TEXT;
929
930
931 p1.namespace = webdav_dav_namespace();
932 p1.lang =
NULL;
933 p1.name =
"test1";
934 p1.value.data = (WSXmlData){
NULL,
NULL,
0};
935 p1.vtype =
0;
936
937 for(
int i=
0;i<
8;i++) {
938 p[i].namespace = webdav_dav_namespace();
939 p[i].name = names[i];
940 p[i].lang =
NULL;
941 p[i].value.node =
NULL;
942 p[
1].vtype =
0;
943 }
944
945 UCX_TEST_ASSERT(!r->plist_begin && !r->plist_end,
"plist not empty");
946
947 r->resource.addproperty((WebdavResource*)r, &p1,
200);
948 UCX_TEST_ASSERT(r->plist_begin,
"!plist_begin");
949 UCX_TEST_ASSERT(r->plist_begin == r->plist_end,
"plist begin != end");
950
951 r->resource.addproperty((WebdavResource*)r, &p[
0],
404);
952 r->resource.addproperty((WebdavResource*)r, &p[
1],
404);
953 r->resource.addproperty((WebdavResource*)r, &p[
2],
403);
954 r->resource.addproperty((WebdavResource*)r, &p[
3],
403);
955 r->resource.addproperty((WebdavResource*)r, &p[
4],
403);
956 r->resource.addproperty((WebdavResource*)r, &p[
5],
403);
957 r->resource.addproperty((WebdavResource*)r, &p[
6],
500);
958
959 UCX_TEST_ASSERT(r->plist_begin == r->plist_end,
"plist begin != end");
960
961 UCX_TEST_ASSERT(r->errors,
"no prop errors");
962 UCX_TEST_ASSERT(r->errors->next,
"no second error code");
963 UCX_TEST_ASSERT(r->errors->next->next,
"no third error code");
964 UCX_TEST_ASSERT(!r->errors->next->next->next,
"too many error codes");
965
966 UCX_TEST_ASSERT(webdav_plist_size(r->errors->begin) ==
2,
"404 list size != 2");
967 UCX_TEST_ASSERT(webdav_plist_size(r->errors->next->begin) ==
4,
"403 list size != 4");
968 UCX_TEST_ASSERT(webdav_plist_size(r->errors->next->next->begin) ==
1,
"500 list size != 1");
969
970
971 r = (MSResponse*)ms->response.addresource((WebdavResponse*)ms,
"/test");
972 UCX_TEST_ASSERT(r,
"cannot create second response");
973
974 r->resource.addproperty((WebdavResource*)r, &dp1,
200);
975 UCX_TEST_ASSERT(r->plist_begin,
"adding dp1 failed");
976 UCX_TEST_ASSERT(!r->plist_begin->next,
"dp1: list size not 1");
977
978 r->resource.addproperty((WebdavResource*)r, &dp2,
200);
979 UCX_TEST_ASSERT(!r->plist_begin->next,
"dp1: adding dp2 should not work");
980
981 r->resource.addproperty((WebdavResource*)r, &dp2,
404);
982 UCX_TEST_ASSERT(!r->plist_begin->next,
"dp1: adding dp2 with different status should not work (1)");
983 if(r->errors) {
984 UCX_TEST_ASSERT(webdav_plist_size(r->errors->begin) ==
0,
"dp1: error list not empty");
985 }
986
987 r->resource.addproperty((WebdavResource*)r, &dp3,
200);
988 UCX_TEST_ASSERT(!r->plist_begin->next,
"dp1: adding dp3 should not work");
989
990 UCX_TEST_END;
991 }
992
993 UCX_TEST(test_webdav_propfind_init) {
994 reset_backends();
995
996 Session *sn;
997 Request *rq;
998 WebdavPropfindRequest *propfind;
999 UCX_TEST_BEGIN;
1000 UCX_TEST_ASSERT(!test_init(&sn, &rq, &propfind,
TEST_PROPFIND1),
"init failed");
1001
1002 WebdavPropfindRequestList *requests =
NULL;
1003 int err = webdav_propfind_init(&backend1, propfind,
"/",
"/", &requests);
1004
1005 UCX_TEST_ASSERT(!err,
"webdav_propfind_init failed");
1006 UCX_TEST_ASSERT(requests,
"request list is empty");
1007 UCX_TEST_ASSERT(cx_linked_list_size(requests, offsetof(WebdavPropfindRequestList, next)),
"request list has wrong size");
1008
1009 WebdavPropfindRequest *p1 = requests->propfind;
1010 WebdavPropfindRequest *p2 = requests->next->propfind;
1011
1012
1013
1014
1015 UCX_TEST_ASSERT(p1 && p2,
"missing requests objects");
1016 UCX_TEST_ASSERT(p1 != p2,
"request objects equal");
1017 UCX_TEST_ASSERT(p1->properties != p2->properties,
"plists equal");
1018 UCX_TEST_ASSERT(p1->propcount == p2->propcount +
1,
"first property not removed");
1019
1020 UCX_TEST_ASSERT(backend1_init_called ==
1,
"backend1 init not called");
1021 UCX_TEST_ASSERT(backend2_init_called ==
1,
"backend2 init not called");
1022
1023 UCX_TEST_END;
1024
1025 pool_destroy(sn->pool);
1026 }
1027
1028 UCX_TEST(test_webdav_op_propfind_begin) {
1029 reset_backends();
1030
1031 Session *sn;
1032 Request *rq;
1033
1034 UCX_TEST_BEGIN;
1035 WebdavOperation *op = test_propfind_op(&sn, &rq,
TEST_PROPFIND1);
1036 UCX_TEST_ASSERT(op,
"WebdavOperation not created");
1037
1038 int err = webdav_op_propfind_begin(op,
"/",
NULL,
NULL);
1039 UCX_TEST_ASSERT(err ==
0,
"err not 0");
1040 UCX_TEST_ASSERT(backend1_propfind_do_count ==
1,
"backend1 propfind_do not called");
1041 UCX_TEST_ASSERT(backend2_propfind_do_count ==
1,
"backend2 propfind_do not called");
1042
1043
1044 UCX_TEST_END;
1045 testutil_destroy_session(sn);
1046 }
1047
1048 UCX_TEST(test_webdav_op_propfind_children) {
1049 reset_backends();
1050
1051 Session *sn;
1052 Request *rq;
1053
1054 UCX_TEST_BEGIN;
1055 WebdavOperation *op = test_propfind_op(&sn, &rq,
TEST_PROPFIND1);
1056 UCX_TEST_ASSERT(op,
"WebdavOperation not created");
1057
1058 int err = webdav_op_propfind_begin(op,
"/",
NULL,
NULL);
1059 UCX_TEST_ASSERT(err ==
0,
"propfind_begin error");
1060
1061
1062 rq->vfs = testvfs_create(sn);
1063 VFSContext *vfs = vfs_request_context(sn, rq);
1064 UCX_TEST_ASSERT(vfs,
"no vfs");
1065
1066 err = vfs_mkdir(vfs,
"/dir");
1067 UCX_TEST_ASSERT(err ==
0,
"error not 0");
1068
1069
1070 UCX_TEST_ASSERT(vfs_open(vfs,
"/dir/file1",
O_CREAT),
"creation of file1 failed");
1071 UCX_TEST_ASSERT(vfs_open(vfs,
"/dir/file2",
O_CREAT),
"creation of file2 failed");
1072 UCX_TEST_ASSERT(vfs_open(vfs,
"/dir/file3",
O_CREAT),
"creation of file3 failed");
1073 UCX_TEST_ASSERT(vfs_open(vfs,
"/dir/file4",
O_CREAT),
"creation of file4 failed");
1074
1075 VFSDir *dir = vfs_opendir(vfs,
"/dir");
1076 UCX_TEST_ASSERT(dir,
"dir not opened");
1077
1078 UCX_TEST_ASSERT(backend1_propfind_do_count ==
1,
"backend1 propfind_do not called");
1079 UCX_TEST_ASSERT(backend2_propfind_do_count ==
1,
"backend1 propfind_do not called")
1080
1081
1082 err = webdav_op_propfind_children(op, vfs,
"/",
"/dir");
1083 UCX_TEST_ASSERT(err ==
0,
"webdav_op_propfind_children failed");
1084
1085
1086 UCX_TEST_ASSERT(backend1_propfind_do_count ==
5,
"backend1 propfind_do wrong count");
1087 UCX_TEST_ASSERT(backend2_propfind_do_count ==
5,
"backend2 propfind_do wrong count");
1088
1089 UCX_TEST_END;
1090 testutil_destroy_session(sn);
1091 }
1092
1093 void init_test_webdav_method(
1094 Session **out_sn,
1095 Request **out_rq,
1096 TestIOStream **out_st,
1097 pblock **out_pb,
1098 const char *method,
1099 const char *path,
1100 const char *request_body)
1101 {
1102 Session *sn;
1103 Request *rq;
1104 TestIOStream *st;
1105 pblock *pb;
1106
1107 sn = testutil_session();
1108 rq = testutil_request(sn->pool, method,
"/");
1109
1110 pblock_nvinsert(
"path", path, rq->vars);
1111 pblock_nvinsert(
"uri", path, rq->reqpb);
1112
1113 st = testutil_iostream(
2048,
TRUE);
1114 sn->csd = (IOStream*)st;
1115
1116 if(request_body) {
1117 testutil_request_body(sn, rq, request_body, strlen(request_body));
1118 }
1119
1120 pb = pblock_create_pool(sn->pool,
4);
1121
1122 *out_sn = sn;
1123 *out_rq = rq;
1124 *out_st = st;
1125 *out_pb = pb;
1126 }
1127
1128 UCX_TEST(test_webdav_propfind) {
1129 Session *sn;
1130 Request *rq;
1131 TestIOStream *st;
1132 pblock *pb;
1133
1134 UCX_TEST_BEGIN;
1135
1136 int ret;
1137
1138 init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPFIND",
"/",
TEST_PROPFIND1);
1139
1140 ret = webdav_propfind(pb, sn, rq);
1141
1142 UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_propfind (1) failed");
1143
1144 xmlDoc *doc = xmlReadMemory(
1145 st->buf->space, st->buf->size,
NULL,
NULL,
0);
1146 UCX_TEST_ASSERT(doc,
"propfind1: response is not valid xml");
1147
1148
1149
1150 testutil_destroy_session(sn);
1151 xmlFreeDoc(doc);
1152 testutil_iostream_destroy(st);
1153
1154
1155 init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPFIND",
"/",
TEST_PROPFIND2);
1156
1157 ret = webdav_propfind(pb, sn, rq);
1158
1159 UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_propfind (2) failed");
1160
1161 xmlDoc *doc2 = xmlReadMemory(
1162 st->buf->space, st->buf->size,
NULL,
NULL,
0);
1163 UCX_TEST_ASSERT(doc,
"propfind2: response is not valid xml");
1164
1165
1166
1167 testutil_destroy_session(sn);
1168 xmlFreeDoc(doc2);
1169 testutil_iostream_destroy(st);
1170
1171 UCX_TEST_END;
1172
1173 }
1174
1175
1176
1177
1178
1179
1180
1181 static int test_proppatch_init(
1182 Session **out_sn,
1183 Request **out_rq,
1184 WebdavProppatchRequest **out_proppatch,
1185 const char *xml)
1186 {
1187 if(!webdav_is_initialized) {
1188 if(webdav_init(
NULL,
NULL,
NULL) !=
REQ_PROCEED) {
1189 return 1;
1190 }
1191 webdav_is_initialized =
1;
1192 }
1193
1194 Session *sn = testutil_session();
1195 Request *rq = testutil_request(sn->pool,
"PROPPATCH",
"/");
1196
1197 int error =
0;
1198
1199 WebdavProppatchRequest *proppatch = proppatch_parse(
1200 sn,
1201 rq,
1202 xml,
1203 strlen(xml),
1204 &error);
1205
1206 if(error) {
1207 return 1;
1208 }
1209
1210 if(!proppatch || !(proppatch->set || proppatch->remove)) {
1211 return 1;
1212 }
1213
1214 *out_sn = sn;
1215 *out_rq = rq;
1216 *out_proppatch = proppatch;
1217 return 0;
1218 }
1219
1220 static WebdavOperation* test_proppatch_op1(
1221 Session **out_sn,
1222 Request **out_rq,
1223 const char *xml)
1224 {
1225 WebdavProppatchRequest *proppatch;
1226 if(test_proppatch_init(out_sn, out_rq, &proppatch, xml)) {
1227 return NULL;
1228 }
1229
1230 Multistatus *ms = multistatus_response(*out_sn, *out_rq);
1231 if(!ms) {
1232 return NULL;
1233 }
1234
1235
1236 WebdavResponse *response = (WebdavResponse*)ms;
1237
1238 return webdav_create_proppatch_operation(
1239 (*out_sn),
1240 (*out_rq),
1241 &backend1,
1242 proppatch,
1243 response);
1244 }
1245
1246
1247 UCX_TEST(test_proppatch_msresponse) {
1248 Session *sn;
1249 Request *rq;
1250 WebdavOperation *op;
1251
1252 Multistatus *ms;
1253 WebdavResource *res;
1254
1255 WebdavProperty p[
16];
1256 const char *names[] = {
"a1",
"a2",
"a3",
"a4",
"a5",
"a6",
"a7",
"a8",
"a9"};
1257 for(
int i=
0;i<
8;i++) {
1258 p[i].namespace = webdav_dav_namespace();
1259 p[i].name = names[i];
1260 p[i].lang =
NULL;
1261 p[i].value.node =
NULL;
1262 p[i].vtype =
0;
1263 }
1264
1265 UCX_TEST_BEGIN;
1266
1267 op = test_proppatch_op1(&sn, &rq,
TEST_PROPPATCH2);
1268 UCX_TEST_ASSERT(op,
"failed to create proppatch operation");
1269
1270 ms = (Multistatus*)op->response;
1271 ms->proppatch =
TRUE;
1272 res = ms->response.addresource(&ms->response,
"/");
1273 UCX_TEST_ASSERT(res,
"cannot create resource 1");
1274
1275 UCX_TEST_ASSERT(!res->addproperty(res, &p[
0],
200),
"addproperty 1 failed");
1276 UCX_TEST_ASSERT(!res->addproperty(res, &p[
1],
200),
"addproperty 2 failed");
1277 UCX_TEST_ASSERT(!res->addproperty(res, &p[
2],
200),
"addproperty 3 failed");
1278 UCX_TEST_ASSERT(!res->addproperty(res, &p[
3],
200),
"addproperty 4 failed");
1279
1280 UCX_TEST_ASSERT(!res->close(res),
"close failed");
1281
1282 MSResponse *msres = (MSResponse*)res;
1283 UCX_TEST_ASSERT(!msres->errors,
"error list not NULL");
1284 UCX_TEST_ASSERT(msres->plist_begin,
"elm1 missing");
1285 UCX_TEST_ASSERT(msres->plist_begin->next,
"elm2 missing");
1286 UCX_TEST_ASSERT(msres->plist_begin->next->next,
"elm3 missing");
1287 UCX_TEST_ASSERT(msres->plist_begin->next->next->next,
"elm4 missing");
1288 UCX_TEST_ASSERT(!msres->plist_begin->next->next->next->next,
"count != 4");
1289
1290 UCX_TEST_END;
1291 testutil_destroy_session(sn);
1292 }
1293
1294 UCX_TEST(test_msresponse_addproperty_with_errors) {
1295 Session *sn;
1296 Request *rq;
1297 WebdavOperation *op;
1298
1299 Multistatus *ms;
1300 WebdavResource *res;
1301
1302 WebdavProperty p[
16];
1303 const char *names[] = {
"a1",
"a2",
"a3",
"a4",
"a5",
"a6",
"a7",
"a8",
"a9"};
1304 for(
int i=
0;i<
8;i++) {
1305 p[i].namespace = webdav_dav_namespace();
1306 p[i].name = names[i];
1307 p[i].lang =
NULL;
1308 p[i].value.node =
NULL;
1309 p[i].vtype =
0;
1310 }
1311
1312 UCX_TEST_BEGIN;
1313
1314 op = test_proppatch_op1(&sn, &rq,
TEST_PROPPATCH2);
1315 UCX_TEST_ASSERT(op,
"failed to create proppatch operation");
1316
1317 ms = (Multistatus*)op->response;
1318 ms->proppatch =
TRUE;
1319 res = ms->response.addresource(&ms->response,
"/");
1320 UCX_TEST_ASSERT(res,
"cannot create resource 1");
1321
1322 UCX_TEST_ASSERT(!res->addproperty(res, &p[
0],
200),
"addproperty 1 failed");
1323 UCX_TEST_ASSERT(!res->addproperty(res, &p[
1],
200),
"addproperty 2 failed");
1324 UCX_TEST_ASSERT(!res->addproperty(res, &p[
2],
409),
"addproperty 3 failed");
1325 UCX_TEST_ASSERT(!res->addproperty(res, &p[
3],
200),
"addproperty 4 failed");
1326
1327 UCX_TEST_ASSERT(!res->close(res),
"close failed");
1328
1329
1330
1331
1332 MSResponse *msres = (MSResponse*)res;
1333
1334 UCX_TEST_ASSERT(!msres->plist_begin,
"plist not NULL");
1335 UCX_TEST_ASSERT(msres->errors,
"error list is NULL");
1336 UCX_TEST_ASSERT(msres->errors->next,
"second error list is missing");
1337 UCX_TEST_ASSERT(!msres->errors->next->next,
"wrong error list size");
1338
1339
1340
1341
1342 if(msres->errors->status ==
409) {
1343 UCX_TEST_ASSERT(msres->errors->next->status ==
424,
"wrong status code in second err elm");
1344 UCX_TEST_ASSERT(msres->errors->begin,
"missing 409 property");
1345 UCX_TEST_ASSERT(msres->errors->next->begin,
"missing 424 properties");
1346 }
else {
1347 UCX_TEST_ASSERT(msres->errors->next->status ==
409,
"wrong status code in second err elm");
1348 UCX_TEST_ASSERT(msres->errors->begin,
"missing 424 properties");
1349 UCX_TEST_ASSERT(msres->errors->next->begin,
"missing 409 property");
1350 }
1351
1352 UCX_TEST_END;
1353 testutil_destroy_session(sn);
1354 }
1355
1356 UCX_TEST(test_webdav_op_proppatch) {
1357 Session *sn;
1358 Request *rq;
1359 WebdavOperation *op;
1360
1361 Multistatus *ms;
1362 WebdavResource *res;
1363
1364 WebdavProperty p[
16];
1365 const char *names[] = {
"a1",
"a2",
"a3",
"a4",
"a5",
"a6",
"a7",
"a8",
"a9"};
1366 for(
int i=
0;i<
8;i++) {
1367 p[i].namespace = webdav_dav_namespace();
1368 p[i].name = names[i];
1369 p[i].lang =
NULL;
1370 p[i].value.node =
NULL;
1371 p[
1].vtype =
0;
1372 }
1373
1374 UCX_TEST_BEGIN;
1375
1376
1377 reset_backends();
1378 op = test_proppatch_op1(&sn, &rq,
TEST_PROPPATCH2);
1379 UCX_TEST_ASSERT(op,
"failed to create proppatch operation");
1380
1381 int ret = webdav_op_proppatch(op,
"/",
"/");
1382 UCX_TEST_ASSERT(ret ==
0,
"webdav_op_proppatch failed");
1383 UCX_TEST_ASSERT(backend1_proppatch_commit,
"backend1 no commit");
1384 UCX_TEST_ASSERT(backend2_proppatch_commit,
"backend2 no commit");
1385 UCX_TEST_ASSERT(backend1_proppatch_do_count ==
1,
"backend1 wrong count (1)");
1386 UCX_TEST_ASSERT(backend2_proppatch_do_count ==
1,
"backend1 wrong count (1)");
1387 UCX_TEST_ASSERT(backend1_proppatch_finish_count ==
1,
"backend1 wrong finish count (1)");
1388 UCX_TEST_ASSERT(backend2_proppatch_finish_count ==
1,
"backend1 wrong finish count (1)");
1389
1390
1391 reset_backends();
1392 op = test_proppatch_op1(&sn, &rq,
TEST_PROPPATCH3);
1393 UCX_TEST_ASSERT(op,
"failed to create proppatch operation 2");
1394
1395 ret = webdav_op_proppatch(op,
"/",
"/");
1396 UCX_TEST_ASSERT(ret ==
0,
"webdav_op_proppatch failed (2)");
1397 UCX_TEST_ASSERT(!backend1_proppatch_commit,
"backend1 commit");
1398 UCX_TEST_ASSERT(!backend2_proppatch_commit,
"backend2 commit");
1399
1400
1401 reset_backends();
1402 op = test_proppatch_op1(&sn, &rq,
TEST_PROPPATCH4);
1403 UCX_TEST_ASSERT(op,
"failed to create proppatch operation 3");
1404
1405 ret = webdav_op_proppatch(op,
"/",
"/");
1406 UCX_TEST_ASSERT(ret !=
0,
"webdav_op_proppatch should fail");
1407 UCX_TEST_ASSERT(backend1_proppatch_do_count ==
1,
"backend1 wrong count (2)");
1408 UCX_TEST_ASSERT(backend2_proppatch_do_count ==
1,
"backend1 wrong count (2)");
1409 UCX_TEST_ASSERT(backend1_proppatch_finish_count ==
1,
"backend1 wrong finish count (2)");
1410 UCX_TEST_ASSERT(backend2_proppatch_finish_count ==
0,
"backend1 wrong finish count (2)");
1411
1412 UCX_TEST_END;
1413 testutil_destroy_session(sn);
1414 }
1415
1416 #define xstreq(a, b) (!strcmp((
const char*)a, (
const char*)b))
1417
1418 UCX_TEST(test_webdav_proppatch) {
1419 Session *sn;
1420 Request *rq;
1421 TestIOStream *st;
1422 pblock *pb;
1423
1424 UCX_TEST_BEGIN;
1425
1426 int ret;
1427
1428 init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPPATCH",
"/",
TEST_PROPPATCH2);
1429 rq->davCollection = &backend1;
1430 ret = webdav_proppatch(pb, sn, rq);
1431
1432 UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_proppatch (1) failed");
1433
1434 xmlDoc *doc = xmlReadMemory(
1435 st->buf->space, st->buf->size,
NULL,
NULL,
0);
1436 UCX_TEST_ASSERT(doc,
"proppatch1: response is not valid xml");
1437
1438
1439
1440 xmlNode *root = xmlDocGetRootElement(doc);
1441 UCX_TEST_ASSERT(root,
"proppatch1: no root");
1442
1443 xmlNode *nodeC =
NULL;
1444 xmlNode *node = root->children;
1445 int depth =
1;
1446 while(node) {
1447 const xmlChar *name = node->name;
1448 int nextNode =
1;
1449 if(node->type !=
XML_ELEMENT_NODE) {
1450
1451 }
else if(depth ==
1) {
1452 if(xstreq(name,
"response")) {
1453 nextNode =
0;
1454 }
1455 }
else if(depth ==
2) {
1456 if(xstreq(name,
"propstat")) {
1457 nextNode =
0;
1458 }
1459 }
else if(depth ==
3) {
1460 if(xstreq(name,
"prop")) {
1461 nextNode =
0;
1462 }
1463 }
else if(depth ==
4) {
1464 if(xstreq(name,
"c")) {
1465 nodeC = node;
1466 break;
1467 }
1468 }
1469
1470 if(nextNode) {
1471 node = node->next;
1472 }
else {
1473 node = node->children;
1474 depth++;
1475 }
1476 }
1477
1478 UCX_TEST_ASSERT(nodeC,
"prop c not in response");
1479 UCX_TEST_ASSERT(!nodeC->children,
"properties must not have a value");
1480
1481 testutil_destroy_session(sn);
1482 xmlFreeDoc(doc);
1483 testutil_iostream_destroy(st);
1484
1485
1486 UCX_TEST_END;
1487 }
1488
1489
1490
1491
1492
1493
1494
1495
1496 static int mkcol_data1 =
10;
1497 static int mkcol_data2 =
20;
1498 static int mkcol_data3 =
30;
1499 static int mkcol_data4 =
40;
1500
1501 static int mkcol_count =
0;
1502 static int mkcol_finish_count =
0;
1503
1504 static int mkcol_err =
0;
1505
1506 static int set_created =
0;
1507
1508 static int test_webdav_mkcol(WebdavVFSRequest *req, WSBool *created) {
1509 mkcol_count++;
1510
1511 switch(mkcol_count) {
1512 case 1: {
1513 req->userdata = &mkcol_data1;
1514 break;
1515 }
1516 case 2: {
1517 req->userdata = &mkcol_data2;
1518 break;
1519 }
1520 case 3: {
1521 req->userdata = &mkcol_data3;
1522 break;
1523 }
1524 case 4: {
1525 req->userdata = &mkcol_data4;
1526 break;
1527 }
1528 default:
break;
1529 }
1530
1531 if(set_created) {
1532 *created =
TRUE;
1533 set_created =
0;
1534 }
1535
1536 return 0;
1537 }
1538
1539 static int test_webdav_mkcol_finish(WebdavVFSRequest *req, WSBool success) {
1540 mkcol_finish_count++;
1541
1542 if(mkcol_finish_count ==
1) {
1543 int *data = req->userdata;
1544 if(data != &mkcol_data1) {
1545 mkcol_err =
1;
1546 }
1547 }
else if(mkcol_finish_count ==
3) {
1548 int *data = req->userdata;
1549 if(data != &mkcol_data3) {
1550 mkcol_err =
1;
1551 }
1552 }
else {
1553 int *data = req->userdata;
1554
1555 if(data == &mkcol_data4) {
1556 mkcol_err =
1;
1557 }
1558 }
1559
1560 return 0;
1561 }
1562
1563 static int test_webdav_mkcol_fail(WebdavVFSRequest *req, WSBool *created) {
1564 mkcol_count++;
1565 return 1;
1566 }
1567
1568 static int delete_count =
0;
1569 static int delete_finish_count =
0;
1570
1571 static int test_backend_webdav_delete(WebdavVFSRequest *req, WSBool *created) {
1572 delete_count++;
1573 return 0;
1574 }
1575
1576 static int test_backend_webdav_delete_finish(WebdavVFSRequest *req, WSBool success) {
1577 delete_finish_count++;
1578 return 0;
1579 }
1580
1581
1582 UCX_TEST(test_webdav_vfs_op_do) {
1583 Session *sn;
1584 Request *rq;
1585 TestIOStream *st;
1586 pblock *pb;
1587
1588
1589
1590
1591
1592 init_test_webdav_method(&sn, &rq, &st, &pb,
"MKCOL",
"/",
NULL);
1593 VFS *testvfs = testvfs_create(sn);
1594 rq->vfs = testvfs;
1595
1596 WebdavBackend dav1;
1597 ZERO(&dav1,
sizeof(WebdavBackend));
1598 dav1.opt_mkcol = test_webdav_mkcol;
1599 dav1.opt_mkcol_finish = test_webdav_mkcol_finish;
1600 dav1.opt_delete = test_backend_webdav_delete;
1601 dav1.opt_delete_finish = test_backend_webdav_delete_finish;
1602
1603 WebdavBackend dav2;
1604 ZERO(&dav2,
sizeof(WebdavBackend));
1605 dav2.opt_mkcol_finish = test_webdav_mkcol_finish;
1606
1607 WebdavBackend dav3;
1608 ZERO(&dav3,
sizeof(WebdavBackend));
1609 dav3.opt_mkcol = test_webdav_mkcol;
1610
1611 WebdavBackend dav4;
1612 ZERO(&dav4,
sizeof(WebdavBackend));
1613 dav4.opt_mkcol = test_webdav_mkcol;
1614 dav4.opt_mkcol_finish = test_webdav_mkcol_finish;
1615
1616 dav1.next = &dav2;
1617 dav2.next = &dav3;
1618 dav3.next = &dav4;
1619
1620 rq->davCollection = &dav1;
1621
1622 UCX_TEST_BEGIN;
1623
1624 WebdavVFSOperation *op1 = webdav_vfs_op(sn, rq, &dav1,
FALSE);
1625
1626 int ret = webdav_vfs_op_do(op1,
WEBDAV_VFS_MKDIR);
1627
1628 UCX_TEST_ASSERT(!ret,
"webdav_vfs_op_do failed");
1629 UCX_TEST_ASSERT(mkcol_count ==
3,
"wrong mkcol_count");
1630 UCX_TEST_ASSERT(mkcol_finish_count ==
3,
"wrong mkcol_finish_count");
1631 UCX_TEST_ASSERT(mkcol_err ==
0,
"mkcol_err");
1632
1633
1634 rq->vfs =
NULL;
1635 set_created =
1;
1636
1637 WebdavVFSOperation *op2 = webdav_vfs_op(sn, rq, &dav1,
FALSE);
1638 ret = webdav_vfs_op_do(op2,
WEBDAV_VFS_MKDIR);
1639
1640 UCX_TEST_ASSERT(!ret,
"op2 failed");
1641
1642
1643 mkcol_count =
0;
1644 mkcol_finish_count =
0;
1645 dav1.opt_mkcol = test_webdav_mkcol_fail;
1646
1647 WebdavVFSOperation *op3 = webdav_vfs_op(sn, rq, &dav1,
FALSE);
1648 ret = webdav_vfs_op_do(op3,
WEBDAV_VFS_MKDIR);
1649
1650 UCX_TEST_ASSERT(ret,
"op3 should fail");
1651 UCX_TEST_ASSERT(mkcol_count ==
1,
"op3: wrong mkcol_count");
1652 UCX_TEST_ASSERT(mkcol_finish_count ==
1,
"op3: wrong mkcol_finish_count");
1653
1654
1655 pblock_replace(
"path",
"/deltest", rq->vars);
1656 rq->vfs = testvfs;
1657 WebdavVFSOperation *op_del = webdav_vfs_op(sn, rq, &dav1,
FALSE);
1658 vfs_open(op_del->vfs,
"/deltest",
O_CREAT);
1659 ret = webdav_vfs_op_do(op_del,
WEBDAV_VFS_DELETE);
1660
1661 UCX_TEST_ASSERT(!ret,
"op_del failed");
1662 UCX_TEST_ASSERT(delete_count ==
1,
"op_del: wrong delete_count");
1663 UCX_TEST_ASSERT(delete_finish_count ==
1,
"op_del: wrong delete_finish_count");
1664
1665
1666 UCX_TEST_END;
1667 }
1668
1669 UCX_TEST(test_webdav_delete){
1670 Session *sn;
1671 Request *rq;
1672 TestIOStream *st;
1673 pblock *pb;
1674
1675 init_test_webdav_method(&sn, &rq, &st, &pb,
"DELETE",
"/",
NULL);
1676 rq->vfs = testvfs_create(sn);
1677
1678 WebdavBackend dav1;
1679 ZERO(&dav1,
sizeof(WebdavBackend));
1680 dav1.opt_delete = test_backend_webdav_delete;
1681 dav1.opt_delete_finish = test_backend_webdav_delete_finish;
1682 delete_count =
0;
1683 delete_finish_count =
0;
1684 rq->davCollection = &dav1;
1685
1686 UCX_TEST_BEGIN;
1687
1688
1689 VFSContext *vfs = vfs_request_context(sn, rq);
1690 int err;
1691 err = vfs_mkdir(vfs,
"/dir1");
1692 UCX_TEST_ASSERT(err ==
0,
"mkdir dir1 failed");
1693 err = vfs_mkdir(vfs,
"/dir2");
1694 UCX_TEST_ASSERT(err ==
0,
"mkdir dir2 failed");
1695 err = vfs_mkdir(vfs,
"/dir2/dir3");
1696 UCX_TEST_ASSERT(err ==
0,
"mkdir dir3 failed");
1697 err = vfs_mkdir(vfs,
"/dir2/dir4");
1698 UCX_TEST_ASSERT(err ==
0,
"mkdir dir4 failed");
1699 err = vfs_mkdir(vfs,
"/dir2/dir4/dir5");
1700 UCX_TEST_ASSERT(err ==
0,
"mkdir dir5 failed");
1701
1702 SYS_FILE f0 = vfs_open(vfs,
"/file0",
O_CREAT);
1703 UCX_TEST_ASSERT(f0,
"f0 create failed");
1704
1705 SYS_FILE f2 = vfs_open(vfs,
"/dir2/file2",
O_CREAT);
1706 UCX_TEST_ASSERT(f2,
"f2 create failed");
1707 SYS_FILE f3 = vfs_open(vfs,
"/dir2/dir3/file3",
O_CREAT);
1708 UCX_TEST_ASSERT(f3,
"f3 create failed");
1709 SYS_FILE f4 = vfs_open(vfs,
"/dir2/dir4/file4",
O_CREAT);
1710 UCX_TEST_ASSERT(f4,
"f4 create failed");
1711 SYS_FILE f5 = vfs_open(vfs,
"/dir2/dir4/dir5/file5",
O_CREAT);
1712 UCX_TEST_ASSERT(f5,
"f5 create failed");
1713
1714
1715 pblock_replace(
"path",
"/file0", rq->vars);
1716 err = webdav_delete(
NULL, sn, rq);
1717 UCX_TEST_ASSERT(err ==
0,
"DELETE /file0 failed");
1718 UCX_TEST_ASSERT(delete_count ==
1,
"del1: wrong delete count");
1719
1720 delete_count =
0;
1721 pblock_replace(
"path",
"/dir1", rq->vars);
1722 err = webdav_delete(
NULL, sn, rq);
1723 UCX_TEST_ASSERT(err ==
0,
"DELETE /dir1 failed");
1724 UCX_TEST_ASSERT(delete_count ==
1,
"del1: wrong delete count");
1725
1726 delete_count =
0;
1727 pblock_replace(
"path",
"/dir2", rq->vars);
1728 err = webdav_delete(
NULL, sn, rq);
1729 UCX_TEST_ASSERT(err ==
0,
"DELETE /dir2 failed");
1730 UCX_TEST_ASSERT(delete_count ==
8,
"del2: wrong delete count");
1731
1732 UCX_TEST_END;
1733 }
1734
1735 UCX_TEST(test_webdav_put) {
1736 Session *sn;
1737 Request *rq;
1738 TestIOStream *st;
1739 pblock *pb;
1740
1741 const char *content_const =
"Hello World";
1742
1743 init_test_webdav_method(&sn, &rq, &st, &pb,
"PUT",
"/", content_const);
1744 rq->vfs = testvfs_create(sn);
1745
1746 UCX_TEST_BEGIN;
1747
1748 int err;
1749
1750 pblock_replace(
"path",
"/file0", rq->vars);
1751 err = webdav_put(
NULL, sn, rq);
1752
1753 UCX_TEST_ASSERT(err ==
REQ_PROCEED,
"put failed");
1754
1755 VFSContext *vfs = vfs_request_context(sn, rq);
1756 SYS_FILE f0 = vfs_open(vfs,
"/file0",
0);
1757 UCX_TEST_ASSERT(f0,
"cannot open file0");
1758
1759 char buf[
1024];
1760 int r = system_fread(f0, buf,
1024);
1761
1762 UCX_TEST_ASSERT(r == strlen(content_const),
"wrong file size");
1763 UCX_TEST_ASSERT(!memcmp(content_const, buf, r),
"wrong file content");
1764
1765 testutil_destroy_session(sn);
1766 testutil_iostream_destroy(st);
1767
1768 UCX_TEST_END;
1769 }
1770