161 break; |
166 break; |
162 } |
167 } |
163 } |
168 } |
164 |
169 |
165 // end tag |
170 // end tag |
166 writer_putc(out, '<'); |
171 writer_puts(out, S("</")); |
167 writer_puts(out, sstr((char*)property->namespace->prefix)); |
172 writer_puts(out, sstr((char*)property->namespace->prefix)); |
168 writer_putc(out, ':'); |
173 writer_putc(out, ':'); |
169 writer_puts(out, sstr((char*)property->name)); |
174 writer_puts(out, sstr((char*)property->name)); |
170 writer_putc(out, '>'); |
175 writer_putc(out, '>'); |
171 } else { |
176 } else { |
172 writer_putc(out, '/>'); |
177 writer_puts(out, S("/>")); |
173 } |
178 } |
174 |
179 |
175 return out->error; |
180 return out->error; |
176 } |
181 } |
177 |
182 |
178 static int send_response_tag(Multistatus *ms, MSResponse *rp, Writer *out) { |
183 static int send_response_tag(Multistatus *ms, MSResponse *rp, Writer *out) { |
179 writer_puts(out, S(" <D:response>\n" |
184 writer_puts(out, S(" <D:response>\n" |
180 " <D:href>")); |
185 " <D:href>")); |
181 writer_puts(out, sstr(rp->resource.href)); |
186 writer_puts(out, sstr(rp->resource.href)); |
182 writer_puts(out, S("</href>\n")); |
187 writer_puts(out, S("</D:href>\n")); |
183 |
188 |
184 if(rp->plist_begin) { |
189 if(rp->plist_begin) { |
185 writer_puts(out, S(" <D:propstat>" |
190 writer_puts(out, S(" <D:propstat>\n" |
186 " <D:prop>\n")); |
191 " <D:prop>\n")); |
187 // send properties |
192 // send properties |
188 PropertyOkList *p = rp->plist_begin; |
193 PropertyOkList *p = rp->plist_begin; |
189 while(p) { |
194 while(p) { |
|
195 writer_puts(out, S(" ")); |
190 if(send_property(ms, p->property, p->nsdef, TRUE, out)) { |
196 if(send_property(ms, p->property, p->nsdef, TRUE, out)) { |
191 return out->error; |
197 return out->error; |
192 } |
198 } |
|
199 writer_puts(out, S("\n ")); |
193 p = p->next; |
200 p = p->next; |
194 } |
201 } |
195 |
202 |
196 writer_puts(out, S(" </D:prop>\n" |
203 writer_puts(out, S(" </D:prop>\n" |
197 " <D:status>HTTP/1.1 200 OK</D:status>" |
204 " <D:status>HTTP/1.1 200 OK</D:status>\n" |
198 " </D:propstat>\n")); |
205 " </D:propstat>\n")); |
199 } |
206 } |
200 |
207 |
201 // send error properties |
208 // send error properties |
202 PropertyErrorList *error = rp->errors; |
209 PropertyErrorList *error = rp->errors; |
203 while(error) { |
210 while(error) { |
|
211 writer_puts(out, S(" <D:propstat>\n" |
|
212 " <D:prop>\n")); |
|
213 |
204 WebdavPList *errprop = error->begin; |
214 WebdavPList *errprop = error->begin; |
205 while(errprop) { |
215 while(errprop) { |
|
216 writer_puts(out, S(" ")); |
206 if(send_property(ms, errprop->property, NULL, FALSE, out)) { |
217 if(send_property(ms, errprop->property, NULL, FALSE, out)) { |
207 return out->error; |
218 return out->error; |
208 } |
219 } |
|
220 writer_puts(out, S("\n ")); |
209 errprop = errprop->next; |
221 errprop = errprop->next; |
210 } |
222 } |
|
223 |
|
224 char statuscode[8]; |
|
225 int sclen = snprintf(statuscode, 8, "%d ", error->status); |
|
226 if(sclen > 4) { |
|
227 statuscode[0] = '5'; |
|
228 statuscode[1] = '0'; |
|
229 statuscode[2] = '0'; |
|
230 statuscode[3] = ' '; |
|
231 sclen = 4; |
|
232 } |
|
233 writer_puts(out, S(" </D:prop>\n" |
|
234 " <D:status>HTTP/1.1 ")); |
|
235 writer_put(out, statuscode, sclen); |
|
236 const char *status_msg = protocol_status_message(error->status); |
|
237 if(status_msg) { |
|
238 writer_put(out, status_msg, strlen(status_msg)); |
|
239 } else { |
|
240 writer_puts(out, S("Server Error")); |
|
241 } |
|
242 writer_puts(out, S("</D:status>\n" |
|
243 " </D:propstat>\n")); |
|
244 |
|
245 |
211 error = error->next; |
246 error = error->next; |
212 } |
247 } |
213 |
248 |
|
249 // end response tag |
|
250 writer_puts(out, S(" </D:response>\n")); |
|
251 |
214 return out->error; |
252 return out->error; |
215 } |
253 } |
216 |
254 |
217 int multistatus_send(Multistatus *ms, SYS_NETFD net) { |
255 int multistatus_send(Multistatus *ms, SYS_NETFD net) { |
|
256 // start http response |
|
257 protocol_status(ms->sn, ms->rq, 207, NULL); |
|
258 protocol_start_response(ms->sn, ms->rq); |
|
259 |
218 char buffer[MULTISTATUS_BUFFER_LENGTH]; |
260 char buffer[MULTISTATUS_BUFFER_LENGTH]; |
219 // create a writer, that flushes the buffer when it is filled |
261 // create a writer, that flushes the buffer when it is filled |
220 Writer writer; |
262 Writer writer; |
221 Writer *out = &writer; |
263 Writer *out = &writer; |
222 writer_init(out, net, buffer, MULTISTATUS_BUFFER_LENGTH); |
264 writer_init(out, net, buffer, MULTISTATUS_BUFFER_LENGTH); |