#include "pcheck.h"
#include "../util/pblock.h"
static char* find_param(
char *uri,
char *param)
{
if (param > uri) {
if (*param ==
FILE_PATHSEP) {
--param;
}
while (param > uri && *param !=
FILE_PATHSEP && *param !=
';') {
--param;
}
if (*param ==
';') {
return param;
}
}
return NULL;
}
static PRBool set_path_info(Request *rq,
char *uri,
int path_info_depth)
{
char *path_info = &uri[strlen(uri)];
while (path_info > uri && path_info_depth) {
--path_info;
if (*path_info ==
FILE_PATHSEP) {
--path_info_depth;
}
}
if (*path_info) {
pblock_nvinsert(
"path-info", path_info, rq->vars);
return PR_TRUE;
}
return PR_FALSE;
}
int pcheck_find_path(pblock *pb, Session *sn, Request *rq)
{
char *path = pblock_findkeyval (pb_key_path, rq -> vars);
char *path_info = pblock_findkeyval (pb_key_path_info , rq -> vars);
char *script_name = pblock_findkeyval (pb_key_script_name, rq -> vars);
struct stat stbuf;
struct stat *finfo =
NULL;
rq->directive_is_cacheable =
1;
if (path_info !=
NULL || script_name !=
NULL || path ==
NULL)
return REQ_NOACTION;
if (!*path)
return REQ_NOACTION;
rq->directive_is_cacheable =
0;
path_info = &path[strlen(path) -
1];
char *forward = pblock_findkeyval(pb_key_find_pathinfo_forward, rq->vars);
char *base =
NULL;
if (forward) {
base = pblock_findval(
"ntrans-base" , rq -> vars);
if (!base) forward =
NULL;
}
int path_info_depth =
0;
if(!forward) {
while (
1) {
for( ; path_info != path; --path_info)
if (*path_info ==
FILE_PATHSEP)
break;
for( ; path_info != path; --path_info) {
++path_info_depth;
if (*(path_info -
1) !=
FILE_PATHSEP)
break;
}
if (path_info == path)
break;
*path_info =
'\0';
struct stat *st = request_stat_path(path, rq);
if(st) {
finfo = &stbuf;
stbuf = *st;
free(st);
}
if(finfo) {
if(
S_ISDIR(finfo->st_mode)) {
*path_info =
FILE_PATHSEP;
if (set_path_info(rq, pblock_findkeyval(pb_key_uri, rq->reqpb),
0)) {
return REQ_PROCEED;
}
break;
}
else {
set_path_info(rq, pblock_findkeyval(pb_key_uri, rq->reqpb), path_info_depth);
return REQ_PROCEED;
}
}
else {
*path_info-- =
FILE_PATHSEP;
}
}
return REQ_NOACTION;
}
else {
int baselen = strlen(base);
if (strncmp(path, base, baselen))
return REQ_NOACTION;
path_info = &path[baselen];
if (*path_info ==
'/')
path_info++;
while (
1) {
for( ; *path_info; ++path_info)
if (*path_info ==
FILE_PATHSEP)
break;
if (!*path_info) {
if (set_path_info(rq, pblock_findkeyval(pb_key_uri, rq->reqpb),
0)) {
return REQ_PROCEED;
}
break;
}
*path_info =
'\0';
struct stat *st = request_stat_path(path, rq);
if(st) {
stbuf = *st;
finfo = &stbuf;
free(st);
}
if(finfo) {
if(
S_ISDIR(finfo->st_mode)) {
*path_info++ =
FILE_PATHSEP;
}
else {
char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
*path_info =
FILE_PATHSEP;
#ifdef XP_WIN32
char *unmpath = pblock_findval(
"unmuri", rq->vars);
if (unmpath) {
char *nm = &path_info[strlen(path_info)-
1];
char *unm = &unmpath[strlen(unmpath)-
1];
while(nm != path_info && unm != unmpath) {
if (*nm != *unm) {
if (*unm ==
'\\' && *nm ==
'/')
*nm = *unm;
else
PR_ASSERT(
0);
}
nm--;
unm--;
}
uri = unmpath;
}
#endif
char *t = path_info;
for(; *t; ++t)
if (*t ==
FILE_PATHSEP)
++path_info_depth;
*path_info =
'\0';
set_path_info(rq, uri, path_info_depth);
return REQ_PROCEED;
}
}
else {
*path_info =
FILE_PATHSEP;
break;
}
}
return REQ_NOACTION;
}
}