1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 #include "pcheck.h"
39
40 #include "../util/pblock.h"
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 static char* find_param(
char *uri,
char *param)
57 {
58
59 if (param > uri) {
60 if (*param ==
FILE_PATHSEP) {
61 --param;
62 }
63 while (param > uri && *param !=
FILE_PATHSEP && *param !=
';') {
64 --param;
65 }
66 if (*param ==
';') {
67 return param;
68 }
69 }
70
71 return NULL;
72 }
73
74 static PRBool set_path_info(Request *rq,
char *uri,
int path_info_depth)
75 {
76
77
78 char *path_info = &uri[strlen(uri)];
79 while (path_info > uri && path_info_depth) {
80 --path_info;
81 if (*path_info ==
FILE_PATHSEP) {
82 --path_info_depth;
83 }
84 }
85
86 if (*path_info) {
87 pblock_nvinsert(
"path-info", path_info, rq->vars);
88 return PR_TRUE;
89 }
90
91 return PR_FALSE;
92 }
93
94 int pcheck_find_path(pblock *pb, Session *sn, Request *rq)
95 {
96 char *path = pblock_findkeyval (pb_key_path, rq -> vars);
97 char *path_info = pblock_findkeyval (pb_key_path_info , rq -> vars);
98 char *script_name = pblock_findkeyval (pb_key_script_name, rq -> vars);
99
100 struct stat stbuf;
101 struct stat *finfo =
NULL;
102
103 rq->directive_is_cacheable =
1;
104
105 if (path_info !=
NULL || script_name !=
NULL || path ==
NULL)
106 return REQ_NOACTION;
107
108 if (!*path)
109 return REQ_NOACTION;
110
111
112
113
114
115
116 rq->directive_is_cacheable =
0;
117
118 path_info = &path[strlen(path) -
1];
119
120 char *forward = pblock_findkeyval(pb_key_find_pathinfo_forward, rq->vars);
121 char *base =
NULL;
122 if (forward) {
123 base = pblock_findval(
"ntrans-base" , rq -> vars);
124 if (!base) forward =
NULL;
125 }
126
127 int path_info_depth =
0;
128
129 if(!forward) {
130 while (
1) {
131
132 for( ; path_info != path; --path_info)
133 if (*path_info ==
FILE_PATHSEP)
134 break;
135 for( ; path_info != path; --path_info) {
136 ++path_info_depth;
137 if (*(path_info -
1) !=
FILE_PATHSEP)
138 break;
139 }
140
141 if (path_info == path)
142 break;
143
144 *path_info =
'\0';
145
146 struct stat *st = request_stat_path(path, rq);
147 if(st) {
148 finfo = &stbuf;
149 stbuf = *st;
150 free(st);
151 }
152 if(finfo) {
153
154 if(
S_ISDIR(finfo->st_mode)) {
155 *path_info =
FILE_PATHSEP;
156 if (set_path_info(rq, pblock_findkeyval(pb_key_uri, rq->reqpb),
0)) {
157 return REQ_PROCEED;
158 }
159 break;
160 }
else {
161 set_path_info(rq, pblock_findkeyval(pb_key_uri, rq->reqpb), path_info_depth);
162 return REQ_PROCEED;
163 }
164 }
else {
165 *path_info-- =
FILE_PATHSEP;
166 }
167 }
168
169 return REQ_NOACTION;
170 }
else {
171 int baselen = strlen(base);
172 if (strncmp(path, base, baselen))
173 return REQ_NOACTION;
174
175 path_info = &path[baselen];
176 if (*path_info ==
'/')
177 path_info++;
178
179 while (
1) {
180 for( ; *path_info; ++path_info)
181 if (*path_info ==
FILE_PATHSEP)
182 break;
183
184 if (!*path_info) {
185 if (set_path_info(rq, pblock_findkeyval(pb_key_uri, rq->reqpb),
0)) {
186 return REQ_PROCEED;
187 }
188 break;
189 }
190
191 *path_info =
'\0';
192
193 struct stat *st = request_stat_path(path, rq);
194 if(st) {
195 stbuf = *st;
196 finfo = &stbuf;
197 free(st);
198 }
199 if(finfo) {
200
201 if(
S_ISDIR(finfo->st_mode)) {
202 *path_info++ =
FILE_PATHSEP;
203 }
else {
204 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
205 *path_info =
FILE_PATHSEP;
206 #ifdef XP_WIN32
207 char *unmpath = pblock_findval(
"unmuri", rq->vars);
208 if (unmpath) {
209 char *nm = &path_info[strlen(path_info)-
1];
210 char *unm = &unmpath[strlen(unmpath)-
1];
211 while(nm != path_info && unm != unmpath) {
212 if (*nm != *unm) {
213 if (*unm ==
'\\' && *nm ==
'/')
214 *nm = *unm;
215 else
216 PR_ASSERT(
0);
217 }
218 nm--;
219 unm--;
220 }
221 uri = unmpath;
222 }
223 #endif
224 char *t = path_info;
225 for(; *t; ++t)
226 if (*t ==
FILE_PATHSEP)
227 ++path_info_depth;
228 *path_info =
'\0';
229 set_path_info(rq, uri, path_info_depth);
230 return REQ_PROCEED;
231 }
232 }
233 else {
234 *path_info =
FILE_PATHSEP;
235 break;
236 }
237 }
238
239
240 return REQ_NOACTION;
241 }
242 }
243