| 262 } |
262 } |
| 263 |
263 |
| 264 return out->error; |
264 return out->error; |
| 265 } |
265 } |
| 266 |
266 |
| |
267 static void write_status_str(Writer *out, int status) { |
| |
268 char statuscode[8]; |
| |
269 int sclen = snprintf(statuscode, 8, "%d ", status); |
| |
270 if(sclen > 4) { |
| |
271 statuscode[0] = '5'; |
| |
272 statuscode[1] = '0'; |
| |
273 statuscode[2] = '0'; |
| |
274 statuscode[3] = ' '; |
| |
275 sclen = 4; |
| |
276 } |
| |
277 writer_put_lit(out, "HTTP/1.1 "); |
| |
278 writer_put(out, statuscode, sclen); |
| |
279 const char *status_msg = protocol_status_message(status); |
| |
280 if(status_msg) { |
| |
281 writer_put(out, status_msg, strlen(status_msg)); |
| |
282 } else { |
| |
283 writer_put_lit(out, "Server Error"); |
| |
284 } |
| |
285 } |
| |
286 |
| 267 static int send_response_tag(Multistatus *ms, MSResponse *rp, Writer *out) { |
287 static int send_response_tag(Multistatus *ms, MSResponse *rp, Writer *out) { |
| 268 writer_put_lit(out, " <D:response>\n" |
288 writer_put_lit(out, " <D:response>\n" |
| 269 " <D:href>"); |
289 " <D:href>"); |
| 270 send_string_escaped(out, cx_mutstr(rp->resource.href)); |
290 send_string_escaped(out, cx_mutstr(rp->resource.href)); |
| 271 writer_put_lit(out, "</D:href>\n"); |
291 writer_put_lit(out, "</D:href>\n"); |
| 272 |
292 |
| 273 WSBool writeContent = ms->proppatch ? FALSE : TRUE; |
293 WSBool writeContent = ms->proppatch ? FALSE : TRUE; |
| 274 |
294 |
| 275 if(rp->plist_begin) { |
295 if(rp->resource.status >= 300) { |
| 276 writer_put_lit(out, " <D:propstat>\n" |
296 writer_put_lit(out, " <D:status>"); |
| 277 " <D:prop>\n"); |
297 write_status_str(out, rp->resource.status); |
| 278 // send properties |
298 writer_put_lit(out, "</D:status>\n"); |
| 279 PropertyOkList *p = rp->plist_begin; |
299 |
| 280 while(p) { |
300 } else { |
| 281 writer_put_lit(out, " "); |
301 if(rp->plist_begin) { |
| 282 if(send_property(ms, p->property, p->nsdef, writeContent, out)) { |
302 writer_put_lit(out, " <D:propstat>\n" |
| 283 return out->error; |
303 " <D:prop>\n"); |
| 284 } |
304 // send properties |
| 285 writer_put_lit(out, "\n"); |
305 PropertyOkList *p = rp->plist_begin; |
| 286 p = p->next; |
306 while(p) { |
| 287 } |
307 writer_put_lit(out, " "); |
| 288 |
308 if(send_property(ms, p->property, p->nsdef, writeContent, out)) { |
| 289 writer_put_lit(out, " </D:prop>\n" |
309 return out->error; |
| 290 " <D:status>HTTP/1.1 200 OK</D:status>\n" |
310 } |
| 291 " </D:propstat>\n"); |
311 writer_put_lit(out, "\n"); |
| 292 } |
312 p = p->next; |
| 293 |
313 } |
| 294 // send error properties |
314 |
| 295 PropertyErrorList *error = rp->errors; |
315 writer_put_lit(out, " </D:prop>\n" |
| 296 while(error) { |
316 " <D:status>HTTP/1.1 200 OK</D:status>\n" |
| 297 writer_put_lit(out, " <D:propstat>\n" |
317 " </D:propstat>\n"); |
| 298 " <D:prop>\n"); |
318 } |
| 299 |
319 |
| 300 WebdavPList *errprop = error->begin; |
320 // send error properties |
| 301 while(errprop) { |
321 PropertyErrorList *error = rp->errors; |
| 302 writer_put_lit(out, " "); |
322 while(error) { |
| 303 if(send_property(ms, errprop->property, NULL, FALSE, out)) { |
323 writer_put_lit(out, " <D:propstat>\n" |
| 304 return out->error; |
324 " <D:prop>\n"); |
| 305 } |
325 |
| 306 writer_putc(out, '\n'); |
326 WebdavPList *errprop = error->begin; |
| 307 errprop = errprop->next; |
327 while(errprop) { |
| 308 } |
328 writer_put_lit(out, " "); |
| 309 |
329 if(send_property(ms, errprop->property, NULL, FALSE, out)) { |
| 310 char statuscode[8]; |
330 return out->error; |
| 311 int sclen = snprintf(statuscode, 8, "%d ", error->status); |
331 } |
| 312 if(sclen > 4) { |
332 writer_putc(out, '\n'); |
| 313 statuscode[0] = '5'; |
333 errprop = errprop->next; |
| 314 statuscode[1] = '0'; |
334 } |
| 315 statuscode[2] = '0'; |
335 |
| 316 statuscode[3] = ' '; |
336 writer_put_lit(out, " </D:prop>\n" |
| 317 sclen = 4; |
337 " <D:status>"); |
| 318 } |
338 write_status_str(out, error->status); |
| 319 writer_put_lit(out, " </D:prop>\n" |
339 writer_put_lit(out, "</D:status>\n" |
| 320 " <D:status>HTTP/1.1 "); |
340 " </D:propstat>\n"); |
| 321 writer_put(out, statuscode, sclen); |
341 |
| 322 const char *status_msg = protocol_status_message(error->status); |
342 |
| 323 if(status_msg) { |
343 error = error->next; |
| 324 writer_put(out, status_msg, strlen(status_msg)); |
344 } |
| 325 } else { |
|
| 326 writer_put_lit(out, "Server Error"); |
|
| 327 } |
|
| 328 writer_put_lit(out, "</D:status>\n" |
|
| 329 " </D:propstat>\n"); |
|
| 330 |
|
| 331 |
|
| 332 error = error->next; |
|
| 333 } |
345 } |
| 334 |
346 |
| 335 // end response tag |
347 // end response tag |
| 336 writer_put_lit(out, " </D:response>\n"); |
348 writer_put_lit(out, " </D:response>\n"); |
| 337 |
349 |