src/server/webdav/multistatus.c

branch
webdav
changeset 233
c5985d2fc19a
parent 231
4714468b9b7e
child 237
ee1680ef1ef2
equal deleted inserted replaced
232:499711b2a970 233:c5985d2fc19a
28 28
29 #include <stdio.h> 29 #include <stdio.h>
30 #include <stdlib.h> 30 #include <stdlib.h>
31 31
32 #include "../daemon/session.h" 32 #include "../daemon/session.h"
33 #include "../daemon/protocol.h"
33 #include "../util/platform.h" 34 #include "../util/platform.h"
34 35
35 #include <ucx/string.h> 36 #include <ucx/string.h>
36 37
38 #include "multistatus.h"
39
37 #include "operation.h" 40 #include "operation.h"
38 41 #include "xml.h"
39 #include "multistatus.h"
40 42
41 #define MULTISTATUS_BUFFER_LENGTH 2048 43 #define MULTISTATUS_BUFFER_LENGTH 2048
42 44
43 Multistatus* multistatus_response(Session *sn, Request *rq) { 45 Multistatus* multistatus_response(Session *sn, Request *rq) {
44 Multistatus *ms = pool_malloc(sn->pool, sizeof(Multistatus)); 46 Multistatus *ms = pool_malloc(sn->pool, sizeof(Multistatus));
139 141
140 // content 142 // content
141 switch(property->vtype) { 143 switch(property->vtype) {
142 case WS_VALUE_NO_TYPE: break; 144 case WS_VALUE_NO_TYPE: break;
143 case WS_VALUE_XML_NODE: { 145 case WS_VALUE_XML_NODE: {
144 // TODO 146 wsxml_write_nodes_without_nsdef(
147 ms->sn->pool,
148 out,
149 property->value.node);
145 break; 150 break;
146 } 151 }
147 case WS_VALUE_XML_DATA: { 152 case WS_VALUE_XML_DATA: {
148 // only write data, data->namespaces is already handled 153 // only write data, data->namespaces is already handled
149 writer_put( 154 writer_put(
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);
232 if(send_response_tag(ms, response, out)) { 274 if(send_response_tag(ms, response, out)) {
233 return 1; 275 return 1;
234 } 276 }
235 response = response->next; 277 response = response->next;
236 } 278 }
279
280 // end multistatus
281 writer_puts(out, S("</D:multistatus>\n"));
282
283 writer_flush(out);
237 284
238 return 0; 285 return 0;
239 } 286 }
240 287
241 WebdavResource * multistatus_addresource( 288 WebdavResource * multistatus_addresource(

mercurial