73 return REQ_ABORTED; |
74 return REQ_ABORTED; |
74 } |
75 } |
75 |
76 |
76 printf("PUT length: %d\n", length); |
77 printf("PUT length: %d\n", length); |
77 |
78 |
78 int status = 204; |
79 int status = 201; |
79 if(length >= 0) { |
80 FILE *out = fopen(ppath, "w"); |
80 char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars); |
81 if(out == NULL) { |
81 |
82 fprintf(stderr, "fopen(%s, \"w\") failed\n", ppath); |
|
83 protocol_status(sn, rq, 500, NULL); |
|
84 return REQ_ABORTED; |
|
85 } |
|
86 |
|
87 if(length > 0) { |
82 FILE *out = fopen(ppath, "w"); |
88 FILE *out = fopen(ppath, "w"); |
83 if(out == NULL) { |
89 if(out == NULL) { |
84 fprintf(stderr, "fopen(%s, \"w\") failed\n", ppath); |
90 fprintf(stderr, "fopen(%s, \"w\") failed\n", ppath); |
85 return REQ_ABORTED; |
91 return REQ_ABORTED; |
86 } |
92 } |
87 setvbuf(out, NULL, _IONBF, 0); |
93 setvbuf(out, NULL, _IONBF, 0); |
88 |
94 |
89 size_t l = (length > 4096) ? (4096) : (length); |
95 size_t len = (length > 4096) ? (4096) : (length); |
90 char *buffer = malloc(l); |
96 char *buffer = malloc(len); |
91 |
97 |
92 int r; |
98 int r; |
93 int r2 = 0; |
99 int r2 = 0; |
94 while(r2 < length) { |
100 while(r2 < length) { |
95 r = netbuf_getbytes(sn->inbuf, buffer, l); |
101 r = netbuf_getbytes(sn->inbuf, buffer, len); |
96 if(r == NETBUF_EOF) { |
102 if(r == NETBUF_EOF) { |
97 break; |
103 break; |
98 } |
104 } |
99 fwrite(buffer, 1, r, out); |
105 fwrite(buffer, 1, r, out); |
100 |
106 |
101 r2 += r; |
107 r2 += r; |
102 } |
108 } |
103 |
109 |
104 fclose(out); |
110 free(buffer); |
105 } |
111 } else { |
|
112 |
|
113 } |
|
114 fclose(out); |
106 |
115 |
107 protocol_status(sn, rq, status, NULL); |
116 protocol_status(sn, rq, status, NULL); |
108 pblock_removekey(pb_key_content_type, rq->srvhdrs); |
117 pblock_removekey(pb_key_content_type, rq->srvhdrs); |
109 pblock_nninsert("content-length", 0, rq->srvhdrs); |
118 pblock_nninsert("content-length", 0, rq->srvhdrs); |
110 http_start_response(sn, rq); |
119 http_start_response(sn, rq); |
230 |
239 |
231 /* TODO: check errno only set status */ |
240 /* TODO: check errno only set status */ |
232 protocol_status(sn, rq, 404, NULL); |
241 protocol_status(sn, rq, 404, NULL); |
233 pblock_removekey(pb_key_content_type, rq->srvhdrs); |
242 pblock_removekey(pb_key_content_type, rq->srvhdrs); |
234 pblock_nninsert("content-length", 0, rq->srvhdrs); |
243 pblock_nninsert("content-length", 0, rq->srvhdrs); |
235 http_start_response(sn, rq); |
244 //http_start_response(sn, rq); |
236 |
245 |
237 return REQ_ABORTED; |
246 return REQ_ABORTED; |
238 } |
247 } |
239 |
248 |
240 /* |
249 /* |
304 protocol_status(sn, rq, 207, "Multi Status"); |
313 protocol_status(sn, rq, 207, "Multi Status"); |
305 pblock_removekey(pb_key_content_type, rq->srvhdrs); |
314 pblock_removekey(pb_key_content_type, rq->srvhdrs); |
306 pblock_nvinsert("content-type", "text/xml", rq->srvhdrs); |
315 pblock_nvinsert("content-type", "text/xml", rq->srvhdrs); |
307 pblock_nninsert("content-length", davrq->out->length, rq->srvhdrs); |
316 pblock_nninsert("content-length", davrq->out->length, rq->srvhdrs); |
308 |
317 |
309 pblock_nvinsert("connection", "close", rq->srvhdrs); |
318 //pblock_nvinsert("connection", "close", rq->srvhdrs); |
310 http_start_response(sn, rq); |
319 http_start_response(sn, rq); |
311 |
320 |
312 net_write(sn->csd, davrq->out->ptr, davrq->out->length); |
321 net_write(sn->csd, davrq->out->ptr, davrq->out->length); |
313 |
322 |
314 |
323 |
315 |
324 dav_free_propfind(davrq); |
316 |
325 |
317 return REQ_PROCEED; |
326 return REQ_PROCEED; |
318 } |
327 } |
319 |
328 |
320 int webdav_proppatch(pblock *pb, Session *sn, Request *rq) { |
329 int webdav_proppatch(pblock *pb, Session *sn, Request *rq) { |
406 protocol_status(sn, rq, 207, "Multi Status"); |
415 protocol_status(sn, rq, 207, "Multi Status"); |
407 pblock_removekey(pb_key_content_type, rq->srvhdrs); |
416 pblock_removekey(pb_key_content_type, rq->srvhdrs); |
408 pblock_nvinsert("content-type", "text/xml", rq->srvhdrs); |
417 pblock_nvinsert("content-type", "text/xml", rq->srvhdrs); |
409 pblock_nninsert("content-length", davrq->out->length, rq->srvhdrs); |
418 pblock_nninsert("content-length", davrq->out->length, rq->srvhdrs); |
410 |
419 |
411 pblock_nvinsert("connection", "close", rq->srvhdrs); |
420 //pblock_nvinsert("connection", "close", rq->srvhdrs); |
412 http_start_response(sn, rq); |
421 http_start_response(sn, rq); |
413 |
422 |
414 net_write(sn->csd, davrq->out->ptr, davrq->out->length); |
423 net_write(sn->csd, davrq->out->ptr, davrq->out->length); |
|
424 |
|
425 dav_free_proppatch(davrq); |
415 |
426 |
416 return REQ_PROCEED; |
427 return REQ_PROCEED; |
417 } |
428 } |
418 |
429 |
419 void dav_resource_response(PropfindRequest *davrq, sstr_t path, sstr_t uri) { |
430 void dav_resource_response(PropfindRequest *davrq, sstr_t path, sstr_t uri) { |
483 void dav_propfind_add_prop_error( |
494 void dav_propfind_add_prop_error( |
484 PropfindRequest *davrq, |
495 PropfindRequest *davrq, |
485 DavProperty *prop, |
496 DavProperty *prop, |
486 int error) |
497 int error) |
487 { |
498 { |
|
499 // TODO: different errors |
488 davrq->notFoundProps = ucx_dlist_append(davrq->notFoundProps, prop); |
500 davrq->notFoundProps = ucx_dlist_append(davrq->notFoundProps, prop); |
489 } |
501 } |
490 |
502 |
491 |
503 |
492 |
504 |
493 |
505 |
494 /* WebDAV Default Backend */ |
506 /* WebDAV Default Backend */ |
|
507 static DAVPropertyBackend dav_file_backend = { |
|
508 dav_rq_propfind, |
|
509 dav_rq_proppatch |
|
510 }; |
|
511 |
495 DAVPropertyBackend* create_property_backend() { |
512 DAVPropertyBackend* create_property_backend() { |
496 DAVPropertyBackend *pb = malloc(sizeof(DAVPropertyBackend)); |
513 return &dav_file_backend; |
497 if(pb == NULL) { |
|
498 // |
|
499 } |
|
500 pb->propfind = dav_rq_propfind; |
|
501 pb->proppatch = dav_rq_proppatch; |
|
502 return pb; |
|
503 } |
514 } |
504 |
515 |
505 void dav_rq_propfind(DAVPropertyBackend *b, PropfindRequest *rq ,char *path) { |
516 void dav_rq_propfind(DAVPropertyBackend *b, PropfindRequest *rq ,char *path) { |
506 struct stat st; |
517 struct stat st; |
507 if(stat(path, &st) != 0) { |
518 if(stat(path, &st) != 0) { |
551 |
562 |
552 /*---------------------------------- utils ----------------------------------*/ |
563 /*---------------------------------- utils ----------------------------------*/ |
553 |
564 |
554 /* XmlNsMap */ |
565 /* XmlNsMap */ |
555 |
566 |
556 XmlNsMap* xmlnsmap_create() { |
567 XmlNsMap* xmlnsmap_create(pool_handle_t *pool) { |
557 XmlNsMap *map = malloc(sizeof(XmlNsMap)); |
568 XmlNsMap *map = malloc(sizeof(XmlNsMap)); |
558 UcxMap *uxm = ucx_map_new(16); |
569 UcxMap *uxm = ucx_map_new(16); |
559 if(map == NULL || uxm == NULL) { |
570 if(map == NULL || uxm == NULL) { |
560 return NULL; |
571 return NULL; |
561 } |
572 } |
562 map->map = uxm; |
573 map->map = uxm; |
|
574 map->pool = pool; |
563 return map; |
575 return map; |
564 } |
576 } |
565 |
577 |
566 void xmlnsmap_free(XmlNsMap *map) { |
578 void xmlnsmap_free(XmlNsMap *map) { |
567 /* TODO: implement */ |
579 ucx_map_free(map->map); |
568 } |
580 } |
569 |
581 |
570 XmlNs* xmlnsmap_put(XmlNsMap *map, char *ns) { |
582 XmlNs* xmlnsmap_put(XmlNsMap *map, char *ns) { |
571 XmlNs *xmlns = xmlnsmap_get(map, ns); |
583 XmlNs *xmlns = xmlnsmap_get(map, ns); |
572 if(xmlns != NULL) { |
584 if(xmlns != NULL) { |
573 return xmlns; |
585 return xmlns; |
574 } |
586 } |
575 |
587 |
576 xmlns = malloc(sizeof(XmlNs)); |
588 xmlns = pool_malloc(map->pool, sizeof(XmlNs)); |
577 if(xmlns == NULL) { |
589 if(xmlns == NULL) { |
578 return NULL; |
590 return NULL; |
579 } |
591 } |
580 |
592 |
581 xmlns->xmlns = ns; |
593 xmlns->xmlns = ns; |