📄 props.c
字号:
ne_request_destroy(req); ne_session_destroy(sess); return OK;}/* Macros for easily writing a 207 response body; all expand to * a string literal. */#define MULTI_207(x) "HTTP/1.0 207 Foo\r\nConnection: close\r\n\r\n" \"<?xml version='1.0'?>\r\n" \"<D:multistatus xmlns:D='DAV:'>" x "</D:multistatus>"#define RESP_207(href, x) "<D:response><D:href>" href "</D:href>" x \"</D:response>"#define PSTAT_207(x) "<D:propstat>" x "</D:propstat>"#define STAT_207(s) "<D:status>HTTP/1.1 " s "</D:status>"#define DESCR_207(d) "<D:responsedescription>" d "</D:responsedescription>"#define DESCR_REM "The end of the world, as we know it"#define PROPS_207(x) "<D:prop>" x "</D:prop>"#define APROP_207(n, c) "<D:" n ">" c "</D:" n ">"/* Tests for the 207 interface: send a 207 response body, compare the * re-serialized string returned with that expected. */static int two_oh_seven(void){ static char *ts[][2] = { { MULTI_207(RESP_207("/foo", "")), "start-resp[/foo];end-resp[/foo];" }, /* test for response status handling */ { MULTI_207(RESP_207("/bar", STAT_207("200 OK"))), "start-resp[/bar];end-resp[/bar]-status={200 OK};" }, /* test that empty description == NULL description argument */ { MULTI_207(RESP_207("/bar", STAT_207("200 OK") DESCR_207(""))), "start-resp[/bar];end-resp[/bar]-status={200 OK};" }, /* test multiple responses */ { MULTI_207(RESP_207("/hello/world", STAT_207("200 OK")) RESP_207("/foo/bar", STAT_207("999 French Fries"))), "start-resp[/hello/world];end-resp[/hello/world]-status={200 OK};" "start-resp[/foo/bar];end-resp[/foo/bar]" "-status={999 French Fries};" }, /* test multiple propstats in mulitple responses */ { MULTI_207(RESP_207("/al/pha", PSTAT_207(STAT_207("321 Une")) PSTAT_207(STAT_207("432 Deux")) PSTAT_207(STAT_207("543 Trois"))) RESP_207("/be/ta", PSTAT_207(STAT_207("787 Quatre")) PSTAT_207(STAT_207("878 Cinq")))), "start-resp[/al/pha];" "start-pstat[/al/pha-1];end-pstat[/al/pha-1]-status={321 Une};" "start-pstat[/al/pha-2];end-pstat[/al/pha-2]-status={432 Deux};" "start-pstat[/al/pha-3];end-pstat[/al/pha-3]-status={543 Trois};" "end-resp[/al/pha];" "start-resp[/be/ta];" "start-pstat[/be/ta-1];end-pstat[/be/ta-1]-status={787 Quatre};" "start-pstat[/be/ta-2];end-pstat[/be/ta-2]-status={878 Cinq};" "end-resp[/be/ta];" }, /* test that incomplete responses are completely ignored. */ { MULTI_207("<D:response/>" RESP_207("/", STAT_207("123 Hoorah")) "<D:response/>" "<D:response><D:propstat>hello</D:propstat></D:response>" "<D:response><D:href/></D:response>" RESP_207("/bar", STAT_207("200 OK"))), "start-resp[/];end-resp[/]-status={123 Hoorah};" "start-resp[/bar];end-resp[/bar]-status={200 OK};" }, /* tests for propstat status */ { MULTI_207(RESP_207("/pstat", PSTAT_207("<D:prop/>" STAT_207("666 Doomed")))), "start-resp[/pstat];start-pstat[/pstat-1];" "end-pstat[/pstat-1]-status={666 Doomed};end-resp[/pstat];" }, { MULTI_207(RESP_207("/pstat", PSTAT_207("<D:status/>"))), "start-resp[/pstat];start-pstat[/pstat-1];" "end-pstat[/pstat-1];end-resp[/pstat];" }, /* tests for responsedescription handling */ { MULTI_207(RESP_207("/bar", STAT_207("200 OK") DESCR_207(DESCR_REM))), "start-resp[/bar];end-resp[/bar]-status={200 OK}" "-descr={" DESCR_REM "};" }, { MULTI_207(RESP_207("/bar", PSTAT_207(STAT_207("456 Too Hungry") DESCR_207("Not enough food available")) STAT_207("200 OK") DESCR_207("Not " DESCR_REM))), "start-resp[/bar];" "start-pstat[/bar-1];end-pstat[/bar-1]-status={456 Too Hungry}" "-descr={Not enough food available};" "end-resp[/bar]-status={200 OK}-descr={Not " DESCR_REM "};" }, /* intermingle some random elements and cdata to make sure * they are ignored. */ { MULTI_207("<D:fish-food/>blargl" RESP_207("/b<ping-pong/>ar", "<D:sausages/>" PSTAT_207("<D:hello-mum/>blergl") STAT_207("200 <pong-ping/> OK") "foop" DESCR_207(DESCR_REM) "carroon") "carapi"), "start-resp[/bar];start-pstat[/bar-1];end-pstat[/bar-1];" "end-resp[/bar]-status={200 OK}-descr={" DESCR_REM "};" }, /* test for properties within a 207. */ { MULTI_207(RESP_207("/alpha", PSTAT_207(PROPS_207( APROP_207("propone", "hello") APROP_207("proptwo", "foobar")) STAT_207("200 OK")))), "start-resp[/alpha];start-pstat[/alpha-1];" "start-prop[/alpha,/alpha-1,propone];cdata-prop[hello];" "end-prop[propone];" "start-prop[/alpha,/alpha-1,proptwo];cdata-prop[foobar];" "end-prop[proptwo];" "end-pstat[/alpha-1]-status={200 OK};end-resp[/alpha];" } }; size_t n; for (n = 0; n < sizeof(ts)/sizeof(ts[0]); n++) CALL(run_207_response(ts[n][0], ts[n][1])); return OK;}/* Serialize propfind result callbacks into a string */static int simple_iterator(void *buf, const ne_propname *name, const char *value, const ne_status *st){ char code[20]; ne_buffer_concat(buf, "prop:[{", name->nspace, ",", name->name, "}=", NULL); if (value) ne_buffer_concat(buf, "'", value, "'", NULL); else ne_buffer_zappend(buf, "#novalue#"); sprintf(code, ":{%d ", st->code); if (st->reason_phrase) ne_buffer_concat(buf, code, st->reason_phrase, "}];", NULL); else ne_buffer_concat(buf, code, "#noreason#}];", NULL); return 0;}static void simple_results(void *buf, const char *href, const ne_prop_result_set *rset){ ne_buffer_concat(buf, "results(", href, ",", NULL); ne_propset_iterate(rset, simple_iterator, buf); ne_buffer_zappend(buf, ")//");}static int diffcmp(const char *expected, const char *actual){ size_t n; if (!strcmp(expected, actual)) return OK; for (n = 0; expected[n] && actual[n]; n++) { if (expected[n] != actual[n]) { t_context("difference at byte %" NE_FMT_SIZE_T ": " "`%.6s...' not `%.6s...'", n, actual+n, expected+n); break; } } return FAIL;} static int run_simple_propfind(const ne_propname *props, char *resp, int depth, const char *expected){ ne_session *sess = ne_session_create("http", "localhost", 7777); ne_buffer *buf = ne_buffer_create(); CALL(spawn_server(7777, single_serve_string, resp)); ONREQ(ne_simple_propfind(sess, "/propfind", depth, props, simple_results, buf)); CALL(await_server()); CALL(diffcmp(expected, buf->data)); ne_buffer_destroy(buf); ne_session_destroy(sess); return OK;}/* a PROPFIND response body for the {DAV:}fishbone property, using * given property value and status. */#define FISHBONE_RESP(value, status) MULTI_207(RESP_207("/foop", \ PSTAT_207(PROPS_207(APROP_207("fishbone", value)) \ STAT_207(status))))static int pfind_simple(void){ static const struct { char *resp; const char *expected; int depth, pset; } ts[] = { /* simple single property. */ { FISHBONE_RESP("hello, world", "212 Well OK"), "results(/foop,prop:[{DAV:,fishbone}='hello, world':{212 Well OK}];)//", 0, 0 }, /* property with some nested elements. */ { FISHBONE_RESP("this is <foo/> a property <bar><lemon>fish</lemon></bar> value", "299 Just About OK"), "results(/foop,prop:[{DAV:,fishbone}=" "'this is <foo></foo> a property " "<bar><lemon>fish</lemon></bar> value':" "{299 Just About OK}];)//", 0, 0 }, /* failed to fetch a property. */ { FISHBONE_RESP("property value is ignored", "404 Il n'ya pas de property"), "results(/foop,prop:[{DAV:,fishbone}=#novalue#:" "{404 Il n'ya pas de property}];)//", 0, 0 },#if 0 /* propstat missing status should be ignored; if a response contains no * valid propstats, it should also be ignored. */ { MULTI_207(RESP_207("/alpha", PSTAT_207(APROP_207("fishbone", "unseen"))) RESP_207("/beta", PSTAT_207(APROP_207("fishbone", "hello, world") STAT_207("200 OK")))), "results(/beta,prop:[{DAV:,fishbone}='hello, world':{200 OK}];)//", 0, 0},#endif /* props on several resources */ { MULTI_207(RESP_207("/alpha", PSTAT_207(PROPS_207(APROP_207("fishbone", "strike one")) STAT_207("234 First is OK"))) RESP_207("/beta", PSTAT_207(PROPS_207(APROP_207("fishbone", "strike two")) STAT_207("256 Second is OK")))), "results(/alpha,prop:[{DAV:,fishbone}='strike one':{234 First is OK}];)//" "results(/beta,prop:[{DAV:,fishbone}='strike two':{256 Second is OK}];)//", 0, 0} }; const ne_propname pset1[] = { { "DAV:", "fishbone", }, { NULL, NULL } }; size_t n; for (n = 0; n < sizeof(ts)/sizeof(ts[0]); n++) { const ne_propname *pset = pset1; CALL(run_simple_propfind(pset, ts[n].resp, ts[n].depth, ts[n].expected)); } return OK;}ne_test tests[] = { T(two_oh_seven), T(patch_simple), T(pfind_simple), T(regress), T(patch_regress), T(NULL) };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -