#include "nametrans.h"
#include "../daemon/log.h"
#include "../daemon/request.h"
#include "../util/pblock.h"
#include "../util/util.h"
#include "../public/webdav.h"
#include "../daemon/session.h"
#include "../daemon/config.h"
#include "../public/vfs.h"
static int initialize_dav_repo(pblock *pb, Session *sn, Request *rq, WebdavRepository *repo) {
if(repo->vfs) {
VFS *vfs = repo->vfs->create(sn, rq, pb, repo->vfsInitData);
if(!vfs) {
return REQ_ABORTED;
}
rq->vfs = vfs;
}
void *backend_first =
NULL;
void *backend_last =
NULL;
CxIterator i = cxListIterator(repo->davBackends);
cx_foreach(WebdavBackendInitData *, davInit, i) {
WebdavBackend *backend = davInit->davType->create(sn, rq, pb, davInit->davInitData);
if(!backend) {
return REQ_ABORTED;
}
cx_linked_list_add(&backend_first, &backend_last, -
1, offsetof(WebdavBackend, next), backend);
}
rq->davCollection = backend_first;
return 0;
}
static int nametrans_set_dav_repository(pblock *pb, Session *sn, Request *rq) {
char *dav = pblock_findkeyval(pb_key_dav, pb);
if(!dav)
return 0;
ServerConfiguration *config = session_get_config(sn);
WebdavRepository *repo = cxMapGet(config->dav, cx_hash_key_str(dav));
if(!repo) {
log_ereport(
LOG_MISCONFIG,
"nametrans: unknown dav repository ''%s''", dav);
return REQ_ABORTED;
}
return initialize_dav_repo(pb, sn, rq, repo);
}
static int nametrans_set_vfs(pblock *pb, Session *sn, Request *rq) {
char *vfsclass = pblock_findkeyval(pb_key_vfsclass, pb);
if(!vfsclass)
return 0;
VFS *vfs = vfs_create(sn, rq, vfsclass, pb,
NULL);
if(!vfs) {
return 1;
}
rq->vfs = vfs;
return 0;
}
static int nametrans_set_dav(pblock *pb, Session *sn, Request *rq) {
char *davclass = pblock_findkeyval(pb_key_davclass, pb);
if(!davclass)
return 0;
WebdavBackend *dav = webdav_create(sn, rq, davclass, pb,
NULL);
rq->davCollection = dav;
return 0;
}
int assign_name(pblock *pb, Session *sn, Request *rq) {
char *name = pblock_findkeyval(pb_key_name, pb);
char *from = pblock_findkeyval(pb_key_from, pb);
if(!name) {
log_ereport(
LOG_MISCONFIG,
"assign-name: missing name parameter");
protocol_status(sn, rq,
500,
NULL);
return REQ_ABORTED;
}
if(from) {
char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
char c;
int i =
0;
while((c = from[i]) !=
0) {
if(c != uri[i]) {
return REQ_NOACTION;
}
i++;
}
}
if(nametrans_set_dav_repository(pb, sn, rq)) {
log_ereport(
LOG_FAILURE,
"assign-name: cannot create dav repository: name=%s from=%s", name, from);
return REQ_ABORTED;
}
if(nametrans_set_vfs(pb, sn, rq)) {
log_ereport(
LOG_FAILURE,
"assign-name: cannot create VFS: name=%s from=%s", name, from);
return REQ_ABORTED;
}
if(nametrans_set_dav(pb, sn, rq)) {
log_ereport(
LOG_FAILURE,
"assign-name: cannot create Webdav Backend: name=%s from=%s", name, from);
return REQ_ABORTED;
}
pblock_kvinsert(pb_key_name, name, strlen(name), rq->vars);
return REQ_NOACTION;
}
int document_root(pblock *pb, Session *sn, Request *rq) {
char *root = pblock_findkeyval(pb_key_root, pb);
if(!root) {
log_ereport(
LOG_MISCONFIG,
"document-root: missing root parameter");
protocol_status(sn, rq,
500,
NULL);
return REQ_ABORTED;
}
if(nametrans_set_vfs(pb, sn, rq)) {
log_ereport(
LOG_FAILURE,
"document-root: cannot create VFS");
return REQ_ABORTED;
}
cxstring root_str = cx_str(root);
cxstring uri_str = cx_str(pblock_findkeyval(pb_key_uri, rq->reqpb));
request_set_path(root_str, uri_str, rq->vars);
return REQ_PROCEED;
}
int pfx2dir(pblock *pb, Session *sn, Request *rq) {
char *from = pblock_findkeyval(pb_key_from, pb);
char *dir = pblock_findkeyval(pb_key_dir, pb);
char *name = pblock_findkeyval(pb_key_name, pb);
if(!from || !dir) {
if(!from && dir) {
log_ereport(
LOG_MISCONFIG,
"pfx2dir: missing from parameter");
}
else if(!dir && from) {
log_ereport(
LOG_MISCONFIG,
"pfx2dir: missing dir parameter");
}
else {
log_ereport(
LOG_MISCONFIG,
"pfx2dir: missing from and dir parameter");
}
protocol_status(sn, rq,
500,
NULL);
return REQ_ABORTED;
}
char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
char fc;
char uc;
int i =
0;
while((fc = from[i]) !=
0) {
uc = uri[i];
if(fc != uc) {
return REQ_NOACTION;
}
i++;
}
uri = uri + i;
if(uri[
0] ==
'/') {
uri++;
}
if(nametrans_set_dav_repository(pb, sn, rq)) {
log_ereport(
LOG_FAILURE,
"pfx2dir: cannot create dav repository: from=%s dir=%s name=%s", from, dir, name);
return REQ_ABORTED;
}
if(nametrans_set_vfs(pb, sn, rq)) {
log_ereport(
LOG_FAILURE,
"pfx2dir: cannot create VFS: from=%s dir=%s name=%s", from, dir, name);
return REQ_ABORTED;
}
if(nametrans_set_dav(pb, sn, rq)) {
log_ereport(
LOG_FAILURE,
"pfx2dir: cannot create Webdav Backend: from=%s dir=%s name=%s", from, dir, name);
return REQ_ABORTED;
}
request_set_path(cx_str(dir), cx_str(uri), rq->vars);
if(name) {
pblock_kvinsert(pb_key_name, name, strlen(name), rq->vars);
}
return REQ_PROCEED;
}
int redirect(pblock *pb, Session *sn, Request *rq) {
char *from = pblock_findval(
"from", pb);
char *url = pblock_findval(
"url", pb);
if(!from || !url) {
log_ereport(
LOG_MISCONFIG,
"redirect: missing parameter (from, url)");
return REQ_ABORTED;
}
char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
if(!strcmp(uri, from)) {
pblock_nvinsert(
"location", url, rq->srvhdrs);
protocol_status(sn, rq,
302,
NULL);
return REQ_ABORTED;
}
return REQ_NOACTION;
}
int simple_rewrite(pblock *pb, Session *sn, Request *rq) {
char *from = pblock_findval(
"from", pb);
char *root = pblock_findval(
"root", pb);
char *path = pblock_findval(
"path", pb);
char *name = pblock_findval(
"name", pb);
if(!from || !path || !root) {
log_ereport(
LOG_MISCONFIG,
"simple-rewrite: missing parameter (from, root, path)");
return REQ_ABORTED;
}
if(nametrans_set_vfs(pb, sn, rq)) {
log_ereport(
LOG_FAILURE,
"simple-rewrite: cannot create VFS: from=%s root=%s path=%s name=%s", from, root, path, name);
return REQ_ABORTED;
}
char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
cxstring u = cx_str(uri);
cxstring f = cx_str(from);
if(cx_strprefix(u, f)) {
cxstring suf = cx_strsubs(u, f.length);
cxmutstr ppath = cx_strcat(
2, cx_str(path), suf);
request_set_path(cx_str(root), (cxstring){ppath.ptr, ppath.length}, rq->vars);
free(ppath.ptr);
if(name) {
pblock_kvinsert(pb_key_name, name, strlen(name), rq->vars);
}
}
return REQ_NOACTION;
}