13be29 | 2018-02-21 | Karl Gustav Sterneberg | | inherit "../pike_test_common";
#include <testsuite.h>
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | | protected string webdav_mount_point;
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | |
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | | protected string basic_auth;
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | |
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | | private Standards.URI base_uri;
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | |
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | | private Protocols.HTTP.Query con;
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | |
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | | private mapping(string:string) base_headers;
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | |
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | |
protected mapping(string:string) current_locks;
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | |
int filesystem_check_exists(string path);
string filesystem_read_file(string path);
|
741b6d | 2018-02-22 | Karl Gustav Sterneberg | | int filesystem_check_content(string path, string expected_data)
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | | {
|
741b6d | 2018-02-22 | Karl Gustav Sterneberg | | string actual_data = filesystem_read_file(path);
TEST_EQUAL(actual_data, expected_data);
return actual_data == expected_data;
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | | }
int filesystem_compare_files(string first_path, string other_path)
{
return filesystem_check_content(other_path, filesystem_read_file(first_path));
}
array(int|mapping(string:string)|string) webdav_request(string method,
string path,
mapping(string:string)|void extra_headers,
string|void data)
{
mapping(string:string) headers = base_headers + ([]);
if (extra_headers) {
headers += extra_headers;
}
array(string) lock_paths = ({ path });
string new_uri = m_delete(headers, "new-uri");
if (new_uri) {
if (lower_case(method) == "copy") {
lock_paths = ({ new_uri });
} else {
lock_paths += ({ new_uri });
}
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | | if (has_prefix(new_uri, "/")) {
new_uri = new_uri[1..];
}
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | | Standards.URI dest_uri = Standards.URI(new_uri, base_uri);
headers["destination"] = (string)dest_uri;
}
multiset(string) locks = (<>);
if (current_locks) {
foreach(lock_paths, string dir) {
while(1) {
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | | string lock = current_locks[dir];
if (lock) {
locks[lock] = 1;
}
if (dir == "/") {
break;
}
dir = dirname(dir);
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | | }
}
if (sizeof(locks)) {
headers->if = "(<" + (indices(locks) * ">), (<") + ">)";
}
}
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | | if (has_prefix(path, "/")) {
path = path[1..];
}
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | |
Standards.URI url = Standards.URI(path, base_uri);
con = Protocols.HTTP.do_method(method, url, UNDEFINED, headers, con, data);
report_debug("Webdav: %s %O (url: %O) ==> code: %d\n",
method, path, url, con?con->status:600);
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | | if (!con) {
return ({ 600, ([]), "" });
}
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | |
return ({ con->status, con->headers, con->data() });
}
int webdav_put(string path, string data)
{
array(int|mapping(string:string)|string) res =
webdav_request("PUT", path, UNDEFINED, data);
if (!((res[0] >= 200) && (res[0] < 300))) {
return 0;
}
return filesystem_check_content(path, data);
}
int webdav_lock(string path, mapping(string:string) locks)
{
string lock_info = #"
<?xml version='1.0' encoding='utf-8'?>
<DAV:lockinfo xmlns:DAV='DAV:'>
<DAV:locktype><DAV:write/></DAV:locktype>
<DAV:lockscope><DAV:exclusive/></DAV:lockscope>
</DAV:lockinfo>
";
array(int|mapping(string:string)|string) res =
webdav_request("LOCK", path, UNDEFINED, lock_info);
if (res[0] != 200) return 0;
if (!res[1]["lock-token"]) return 0;
locks[path] = res[1]["lock-token"];
return 1;
}
void low_unlock(string path, mapping(string:string) locks)
{
m_delete(locks, path);
}
void low_recursive_unlock(string path, mapping(string:string) locks)
{
foreach(indices(locks), string lock_path) {
if (has_prefix(lock_path, path)) {
low_unlock(path, locks);
}
}
}
int webdav_unlock(string path, mapping(string:string) locks)
{
array(int|mapping(string:string)|string) res =
webdav_request("UNLOCK", path, ([
"lock-token": locks[path],
]));
if (!((res[0] >= 200) && (res[0] < 300))) return 0;
low_unlock(path, locks);
return 1;
}
int webdav_delete(string path, mapping(string:string) locks)
{
array(int|mapping(string:string)|string) res =
webdav_request("DELETE", path);
if (!((res[0] >= 200) && (res[0] < 300))) return 0;
low_recursive_unlock(path, locks);
return !filesystem_check_exists(path);
}
int webdav_copy(string src_path, string dst_path)
{
array(int|mapping(string:string)|string) res =
webdav_request("COPY", src_path, ([
"new-uri": dst_path,
]));
if (!((res[0] >= 200) && (res[0] < 300))) return 0;
return filesystem_compare_files(src_path, dst_path);
}
int webdav_move(string src_path, string dst_path, mapping(string:string) locks)
{
string expected_content = filesystem_read_file(src_path);
array(int|mapping(string:string)|string) res =
webdav_request("MOVE", src_path, ([
"new-uri": dst_path,
]));
if (!((res[0] >= 200) && (res[0] < 300))) return 0;
low_recursive_unlock(src_path, locks);
|
741b6d | 2018-02-22 | Karl Gustav Sterneberg | | test_false(filesystem_check_exists, src_path);
test_true(filesystem_check_exists, dst_path);
test_true(filesystem_check_content, dst_path, expected_content);
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | | return
!filesystem_check_exists(src_path) &&
filesystem_check_content(dst_path, expected_content);
}
int webdav_mkcol(string path)
{
array(int|mapping(string:string)|string) res =
webdav_request("MKCOL", path);
return (res[0] >= 200) && (res[0] < 300);
}
int webdav_ls(string path, array(string) expected)
{
string propfind = #"
<?xml version='1.0' encoding='utf-8'?>
<DAV:propfind xmlns:DAV='DAV:'>
<DAV:propname/>
</DAV:propfind>
";
array(int|mapping(string:string)|string) res =
webdav_request("PROPFIND", path, UNDEFINED, propfind);
report_debug("Webdav: propfind result: %d\n%O\n", res[0], res[2]);
TEST_TRUE(res[0] >= 200 && res[0] < 300);
if (res[0] < 200 || res[0] > 300) {
return 0;
}
Parser.XML.Tree.SimpleRootNode root_node =
Parser.XML.Tree.simple_parse_input(res[2]);
array(Parser.XML.Tree.AbstractNode) multistatus_nodes =
root_node->get_elements("DAV:multistatus", true);
TEST_TRUE(sizeof(multistatus_nodes) > 0);
array(Parser.XML.Tree.AbstractNode) response_nodes =
Array.flatten(multistatus_nodes->get_elements("DAV:response", true));
TEST_TRUE(sizeof(response_nodes) > 0);
array(Parser.XML.Tree.AbstractNode) href_nodes =
Array.flatten(response_nodes->get_elements("DAV:href", true));
TEST_TRUE(sizeof(href_nodes) > 0);
array(string) hrefs = href_nodes->value_of_node();
array(string) actual = Array.flatten(map(hrefs,
lambda(string href) {
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | |
string webdav_mp = webdav_mount_point;
if (!has_suffix(webdav_mp, "/")) {
webdav_mp += "/";
}
return array_sscanf(href, "%*s"+webdav_mp+"%s");
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | | }));
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | |
array(string) expected_ = map(expected,
lambda(string path) { return has_prefix(path, "/") ? path[1..] : path; });
actual = filter(actual, lambda(string str) { return sizeof(str) > 0; });
expected_ = filter(expected_, lambda(string str) { return sizeof(str) > 0; });
TEST_EQUAL(sort(expected_), sort(actual));
return equal(sort(expected_), sort(actual));
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | | }
void setup();
void run_tests(Configuration conf)
{
setup();
foreach(conf->registered_urls, string full_url) {
mapping(string:string|Configuration|array(Protocol)) port_info =
roxen.urls[full_url];
if (!test_true(mappingp, port_info)) continue;
array(Protocol) ports = port_info->ports;
if (!test_true(arrayp, ports)) continue;
foreach(ports, Protocol prot) {
if (!test_true(stringp, prot->prot_name)) continue;
if (prot->prot_name != "http") continue;
if (prot->bound != 1) continue;
if (!test_true(mappingp, prot->urls)) continue;
string url = (full_url/"#")[0];
mapping(string:mixed) url_data = prot->urls[url];
if (!test_true(mappingp, url_data)) continue;
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | |
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | | report_debug("url data: %O\n", url_data);
test_true(`==, url_data->conf, conf);
test_true(`==, url_data->port, prot);
test_true(stringp, url_data->hostname);
test_true(stringp, url_data->path || "/");
Standards.URI url_uri = Standards.URI(url, "http://*/");
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | | base_uri = Standards.URI(Stdio.append_path(url_data->path || "/",
webdav_mount_point),
url_uri);
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | | base_uri->port = prot->port;
base_uri->host = prot->ip;
if (basic_auth) {
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | | base_uri->user = (basic_auth/":")[0];
base_uri->password = (basic_auth/":")[1..] * ":";
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | | }
report_debug("Webdav testsuite: Base URI: %s\n", (string)base_uri);
base_headers = ([
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | | "host": url_uri->host,
"user-agent": "Roxen WebDAV Tester",
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | | ]);
con = 0;
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | | do_run_tests();
|
13be29 | 2018-02-21 | Karl Gustav Sterneberg | | }
}
}
|
c5d921 | 2018-02-21 | Karl Gustav Sterneberg | |
string get_testdir();
void do_run_tests() {
string testdir = get_testdir();
if (!has_prefix(testdir, "/")) {
testdir = "/" + testdir;
}
if (!has_suffix(testdir, "/")) {
testdir += "/";
}
report_debug("Webdav: testdir is: %O\n", testdir);
mapping(string:string) locks = ([]);
test_true(webdav_delete, testdir, locks);
test_true(webdav_mkcol, testdir);
test_true(webdav_ls, testdir, ({ testdir }));
test_true(webdav_put, testdir+"test_file.txt", "TEST FILE\n");
test_true(webdav_ls, testdir, ({ testdir,
testdir+"test_file.txt" }));
test_true(webdav_lock, testdir+"test_file.txt", locks);
test_false(webdav_lock, testdir+"test_file.txt", ([]));
test_false(webdav_put, testdir+"test_file.txt", "TEST FILE 2\n");
test_false(webdav_delete, testdir+"test_file.txt", locks);
current_locks = locks + ([]);
test_true(webdav_put, testdir+"test_file.txt", "TEST FILE 3\n");
test_true(webdav_unlock, testdir+"test_file.txt", locks);
test_false(webdav_put, testdir+"test_file.txt", "TEST FILE 4\n");
current_locks = locks + ([]);
test_true(webdav_put, testdir+"test_file.txt", "TEST FILE 5\n");
test_true(webdav_lock, testdir+"test_file.txt", locks);
test_false(webdav_delete, testdir+"test_file.txt", locks);
current_locks = locks + ([]);
test_true(webdav_delete, testdir+"test_file.txt", locks);
test_false(webdav_put, testdir+"test_file.txt", "TEST FILE 6\n");
current_locks = locks + ([]);
test_true(webdav_put, testdir+"test_file.txt", "TEST FILE 7\n");
test_true(webdav_delete, testdir+"test_file.txt", locks);
test_true(webdav_mkcol, testdir+"test_dir");
test_true(webdav_mkcol, testdir+"test_dir/sub_dir");
test_true(webdav_put, testdir+"test_dir/test_file.txt", "TEST FILE\n");
test_true(webdav_lock, testdir+"test_dir/test_file.txt", locks);
test_false(webdav_move, testdir+"test_dir/test_file.txt", testdir+"test_file.txt", locks);
test_true(webdav_copy, testdir+"test_dir/test_file.txt", testdir+"test_file.txt");
test_false(webdav_copy, testdir+"test_file.txt", testdir+"test_dir/test_file.txt");
current_locks = locks + ([]);
test_true(webdav_move, testdir+"test_dir/test_file.txt", testdir+"test_file_2.txt", locks);
test_false(webdav_copy, testdir+"test_file.txt", testdir+"test_dir/test_file.txt");
current_locks = locks + ([]);
test_true(webdav_copy, testdir+"test_file.txt", testdir+"test_dir/test_file.txt");
test_true(webdav_lock, testdir+"test_dir/test_file.txt", locks);
test_false(webdav_copy, testdir+"test_file.txt", testdir+"test_dir/test_file.txt");
current_locks = locks + ([]);
test_true(webdav_copy, testdir+"test_file.txt", testdir+"test_dir/test_file.txt");
test_true(webdav_unlock, testdir+"test_dir/test_file.txt", locks);
}
|