50 ZERO(ms, sizeof(Multistatus)); |
50 ZERO(ms, sizeof(Multistatus)); |
51 ms->response.addresource = multistatus_addresource; |
51 ms->response.addresource = multistatus_addresource; |
52 ms->sn = sn; |
52 ms->sn = sn; |
53 ms->rq = rq; |
53 ms->rq = rq; |
54 ms->namespaces = ucx_map_new_a(session_get_allocator(ms->sn), 8); |
54 ms->namespaces = ucx_map_new_a(session_get_allocator(ms->sn), 8); |
|
55 ms->proppatch = FALSE; |
55 if(!ms->namespaces) { |
56 if(!ms->namespaces) { |
56 return NULL; |
57 return NULL; |
57 } |
58 } |
58 if(ucx_map_cstr_put(ms->namespaces, "D", webdav_dav_namespace())) { |
59 if(ucx_map_cstr_put(ms->namespaces, "D", webdav_dav_namespace())) { |
59 return NULL; |
60 return NULL; |
431 property->namespace)) |
432 property->namespace)) |
432 { |
433 { |
433 return 1; // OOM |
434 return 1; // OOM |
434 } |
435 } |
435 } |
436 } |
|
437 } |
|
438 |
|
439 if(response->multistatus->proppatch && response->errors) { |
|
440 // in a proppatch request all operations must succeed |
|
441 // if we have an error, the property update status code must be |
|
442 // 424 Failed Dependency |
|
443 status = 424; |
436 } |
444 } |
437 |
445 |
438 // error properties will be added to a separate list |
446 // error properties will be added to a separate list |
439 if(status != 200) { |
447 if(status != 200) { |
440 return msresponse_addproperror(response, property, status); |
448 return msresponse_addproperror(response, property, status); |
543 int msresponse_close(WebdavResource *res) { |
551 int msresponse_close(WebdavResource *res) { |
544 MSResponse *response = (MSResponse*)res; |
552 MSResponse *response = (MSResponse*)res; |
545 if(response->closing) { |
553 if(response->closing) { |
546 return 0; // close already in progress |
554 return 0; // close already in progress |
547 } |
555 } |
|
556 Multistatus *ms = response->multistatus; |
548 |
557 |
549 int ret = REQ_PROCEED; |
558 int ret = REQ_PROCEED; |
550 WebdavOperation *op = response->multistatus->response.op; |
559 WebdavOperation *op = ms->response.op; |
551 if(webdav_op_propfiond_close_resource(op, res)) { |
560 if(op->response_close(op, res)) { |
552 ret = REQ_ABORTED; |
561 ret = REQ_ABORTED; |
553 } |
562 } |
554 |
563 |
555 // add missing properties with status code 404 |
564 // add missing properties with status code 404 |
556 UcxAllocator *a = session_get_allocator(response->multistatus->sn); |
565 UcxAllocator *a = session_get_allocator(ms->sn); |
557 WebdavPList *pl = response->multistatus->response.op->reqprops; |
566 WebdavPList *pl = ms->response.op->reqprops; |
558 while(pl) { |
567 while(pl) { |
559 sstr_t key = sstrcat_a( |
568 sstr_t key = sstrcat_a( |
560 a, |
569 a, |
561 3, |
570 3, |
562 sstr((char*)pl->property->namespace->href), |
571 sstr((char*)pl->property->namespace->href), |
563 S("\0"), |
572 S("\0"), |
564 sstr((char*)pl->property->name)); |
573 sstr((char*)pl->property->name)); |
565 if(!ucx_map_sstr_get(response->properties, key)) { |
574 if(!ucx_map_sstr_get(response->properties, key)) { |
566 // property was not added to this response |
575 // property was not added to this response |
567 if(msresponse_addproperror(response, pl->property, 404)) { |
576 if(ms->proppatch) { |
568 ret = REQ_ABORTED; |
577 if(msresponse_addproperror(response, pl->property, 424)) { |
569 break; |
578 ret = REQ_ABORTED; |
|
579 break; |
|
580 } |
|
581 } else { |
|
582 if(msresponse_addproperror(response, pl->property, 404)) { |
|
583 ret = REQ_ABORTED; |
|
584 break; |
|
585 } |
570 } |
586 } |
571 } |
587 } |
572 |
588 |
573 pl = pl->next; |
589 pl = pl->next; |
|
590 } |
|
591 |
|
592 if(ms->proppatch && response->errors) { |
|
593 // a proppatch response must succeed entirely |
|
594 // if we have a single error prop, move all props with status 200 |
|
595 // to the error list |
|
596 PropertyOkList *elm = response->plist_begin; |
|
597 PropertyOkList *nextelm; |
|
598 while(elm) { |
|
599 if(msresponse_addproperror(response, elm->property, 424)) { |
|
600 return 1; |
|
601 } |
|
602 nextelm = elm->next; |
|
603 pool_free(response->multistatus->sn->pool, elm); |
|
604 elm = nextelm; |
|
605 } |
|
606 response->plist_begin = NULL; |
|
607 response->plist_end = NULL; |
574 } |
608 } |
575 |
609 |
576 // we don't need the properties anymore |
610 // we don't need the properties anymore |
577 ucx_map_free(response->properties); |
611 ucx_map_free(response->properties); |
578 |
612 |