2 MiddleMan filtering proxy server
3 Copyright (C) 2002 Jason McLaughlin
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 load <rewrite> section from XML file into a linked list
27 REWRITE_LIST *rewrite_load(REWRITE_LIST * rewrite_list, XML_LIST * xml_list)
29 REWRITE_LIST *tmp_list = rewrite_list;
30 struct REWRITE_LIST_LIST *rewrite = NULL;
32 if (tmp_list == NULL) {
33 tmp_list = xmalloc(sizeof(REWRITE_LIST));
34 tmp_list->rewrite = NULL;
36 tmp_list->enabled = TRUE;
38 rewrite_list = tmp_list;
40 pthread_rwlock_init(&tmp_list->lock, NULL);
42 rewrite = tmp_list->rewrite;
44 while ((xml_list = xml_section(xml_list, "<rewrite>"))) {
45 XML_LIST_LOOP(xml_list, "<rewrite>") {
46 XML_LIST_CMP(xml_list, "<item>") {
47 rewrite = rewrite_list_new(rewrite);
48 rewrite->id = rewrite_list->id++;
50 if (tmp_list->rewrite == NULL)
51 tmp_list->rewrite = rewrite;
52 XML_LIST_LOOP(xml_list, "<item>") {
53 XML_LIST_CMP(xml_list, "<enabled>") {
54 xml_list = xml_list->next;
55 if (xml_list->type == XML_VALUE) {
56 if (!strcasecmp(xml_list->item, "false"))
57 rewrite->enabled = FALSE;
59 rewrite->enabled = TRUE;
62 XML_LIST_CMP(xml_list, "<comment>") {
63 xml_list = xml_list->next;
64 if (xml_list->type == XML_VALUE)
65 rewrite_list_insert(rewrite, xml_list->item, NULL, NULL, NULL, NULL, NULL, NULL);
67 XML_LIST_CMP(xml_list, "<pattern>") {
68 xml_list = xml_list->next;
69 if (xml_list->type == XML_VALUE)
70 rewrite_list_insert(rewrite, NULL, xml_list->item, NULL, NULL, NULL, NULL, NULL);
72 XML_LIST_CMP(xml_list, "<replace>") {
73 xml_list = xml_list->next;
74 if (xml_list->type == XML_VALUE)
75 rewrite_list_insert(rewrite, NULL, NULL, xml_list->item, NULL, NULL, NULL, NULL);
77 XML_LIST_CMP(xml_list, "<which>") {
78 xml_list = xml_list->next;
79 if (xml_list->type == XML_VALUE)
80 rewrite_list_insert(rewrite, NULL, NULL, NULL, xml_list->item, NULL, NULL, NULL);
82 XML_LIST_CMP(xml_list, "<host>") {
83 xml_list = xml_list->next;
84 if (xml_list->type == XML_VALUE)
85 rewrite_list_insert(rewrite, NULL, NULL, NULL, NULL, xml_list->item, NULL, NULL);
87 XML_LIST_CMP(xml_list, "<file>") {
88 xml_list = xml_list->next;
89 if (xml_list->type == XML_VALUE)
90 rewrite_list_insert(rewrite, NULL, NULL, NULL, NULL, NULL, xml_list->item, NULL);
92 XML_LIST_CMP(xml_list, "<mime>") {
93 xml_list = xml_list->next;
94 if (xml_list->type == XML_VALUE)
95 rewrite_list_insert(rewrite, NULL, NULL, NULL, NULL, NULL, NULL, xml_list->item);
99 XML_LIST_CMP(xml_list, "<enabled>") {
100 xml_list = xml_list->next;
101 if (xml_list->type == XML_VALUE) {
102 if (!strcasecmp(xml_list->item, "false"))
103 tmp_list->enabled = FALSE;
105 tmp_list->enabled = TRUE;
114 XML_LIST *rewrite_xml(REWRITE_LIST * rewrite_list, XML_LIST * xml_list)
117 struct REWRITE_LIST_LIST *rl;
119 if (rewrite_list == NULL)
122 pthread_rwlock_rdlock(&rewrite_list->lock);
124 xml_list = xml_list_add(xml_list, "<rewrite>", XML_TAG);
126 xml_list = xml_list_add(xml_list, "<enabled>", XML_TAG);
127 xml_list = xml_list_add(xml_list, (rewrite_list->enabled == TRUE) ? "true" : "false", XML_VALUE);
128 xml_list = xml_list_add(xml_list, "</enabled>", XML_TAG);
130 for (rl = rewrite_list->rewrite; rl; rl = rl->next) {
131 xml_list = xml_list_add(xml_list, "<item>", XML_TAG);
133 xml_list = xml_list_add(xml_list, "<enabled>", XML_TAG);
134 xml_list = xml_list_add(xml_list, (rl->enabled == TRUE) ? "true" : "false", XML_VALUE);
135 xml_list = xml_list_add(xml_list, "</enabled>", XML_TAG);
137 if (rl->comment != NULL) {
138 xml_list = xml_list_add(xml_list, "<comment>", XML_TAG);
139 ptr = string_to_xml(rl->comment);
140 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
142 xml_list = xml_list_add(xml_list, "</comment>", XML_TAG);
144 if (rl->host != NULL) {
145 xml_list = xml_list_add(xml_list, "<host>", XML_TAG);
146 ptr = string_to_xml(rl->host);
147 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
149 xml_list = xml_list_add(xml_list, "</host>", XML_TAG);
151 if (rl->file != NULL) {
152 xml_list = xml_list_add(xml_list, "<file>", XML_TAG);
153 ptr = string_to_xml(rl->file);
154 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
156 xml_list = xml_list_add(xml_list, "</file>", XML_TAG);
158 if (rl->mime != NULL) {
159 xml_list = xml_list_add(xml_list, "<mime>", XML_TAG);
160 ptr = string_to_xml(rl->mime);
161 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
163 xml_list = xml_list_add(xml_list, "</mime>", XML_TAG);
165 if (rl->pattern != NULL) {
166 xml_list = xml_list_add(xml_list, "<pattern>", XML_TAG);
167 ptr = string_to_xml(rl->pattern);
168 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
170 xml_list = xml_list_add(xml_list, "</pattern>", XML_TAG);
172 if (rl->replace != NULL) {
173 xml_list = xml_list_add(xml_list, "<replace>", XML_TAG);
174 ptr = string_to_xml(rl->replace);
175 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
177 xml_list = xml_list_add(xml_list, "</replace>", XML_TAG);
180 xml_list = xml_list_add(xml_list, "<which>", XML_TAG);
181 snprintf(buf, sizeof(buf), "%s,%s,%s,%s", (rl->which & REWRITE_SERVER) ? "server" : "", (rl->which & REWRITE_CLIENT) ? "client" : "", (rl->which & REWRITE_BODY) ? "body" : "", (rl->which & REWRITE_POST) ? "post" : "");
182 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
183 xml_list = xml_list_add(xml_list, "</which>", XML_TAG);
185 xml_list = xml_list_add(xml_list, "</item>", XML_TAG);
188 xml_list = xml_list_add(xml_list, "</rewrite>", XML_TAG);
190 pthread_rwlock_unlock(&rewrite_list->lock);
194 void rewrite_list_insert(struct REWRITE_LIST_LIST *x, char *a, char *b, char *c, char *d, char *e, char *f, char *g)
200 FREE_AND_NULL(x->comment);
203 x->comment = xstrdup(a);
209 FREE_AND_NULL(x->pattern);
212 x->pe = reg_sub_compile(b, PCREFLAGS);
213 x->pattern = xstrdup(b);
219 FREE_AND_NULL(x->replace);
222 x->replace = xstrdup(c);
228 args = string_break(d, ',');
229 for (i = 0; args[i]; i++) {
230 if (!strcasecmp(args[i], "server"))
231 x->which |= REWRITE_SERVER;
232 else if (!strcasecmp(args[i], "client"))
233 x->which |= REWRITE_CLIENT;
234 else if (!strcasecmp(args[i], "body"))
235 x->which |= REWRITE_BODY;
236 else if (!strcasecmp(args[i], "post"))
237 x->which |= REWRITE_POST;
248 FREE_AND_NULL(x->host);
251 x->he = reg_compile(e, REGFLAGS);
252 x->host = xstrdup(e);
260 FREE_AND_NULL(x->file);
263 x->fe = reg_compile(f, REGFLAGS);
264 x->file = xstrdup(f);
271 FREE_AND_NULL(x->mime);
274 x->me = reg_compile(g, REGFLAGS);
275 x->mime = xstrdup(g);
281 struct REWRITE_LIST_LIST *rewrite_list_new(struct REWRITE_LIST_LIST *x)
284 x = xmalloc(sizeof(struct REWRITE_LIST_LIST));
287 while (x->next != NULL)
289 x->next = xmalloc(sizeof(struct REWRITE_LIST_LIST));
305 x->which = REWRITE_BODY;
310 struct REWRITE_LIST_LIST *rewrite_list_delete(struct REWRITE_LIST_LIST *x)
312 struct REWRITE_LIST_LIST *start = x;
314 while (start->prev != NULL)
318 x->next->prev = x->prev;
320 x->prev->next = x->next;
332 FREE_AND_NULL(x->comment);
333 FREE_AND_NULL(x->pattern);
334 FREE_AND_NULL(x->replace);
335 FREE_AND_NULL(x->host);
336 FREE_AND_NULL(x->file);
337 FREE_AND_NULL(x->mime);
345 free memory used by REWRITE_LIST-type structure
347 void rewrite_free(REWRITE_LIST * rewrite_list)
352 rewrite_list_free(rewrite_list->rewrite);
354 pthread_rwlock_destroy(&rewrite_list->lock);
359 void rewrite_list_free(struct REWRITE_LIST_LIST *rl)
361 struct REWRITE_LIST_LIST *tmp;
367 reg_sub_free(rl->pe);
374 FREE_AND_NULL(rl->comment);
375 FREE_AND_NULL(rl->pattern);
376 FREE_AND_NULL(rl->replace);
377 FREE_AND_NULL(rl->host);
378 FREE_AND_NULL(rl->file);
379 FREE_AND_NULL(rl->mime);
387 remove areas of text matching patterns in REWRITE_LIST-type struct, and possibly
388 replace with something else
390 int rewrite_do(REWRITE_LIST * rewrite_list, CONNECTION * connection, FILEBUF * filebuf, int flags, int action)
393 struct REWRITE_LIST_LIST *rewrite;
395 if (!rewrite_list || connection->bypass & FEATURE_REWRITE)
398 pthread_rwlock_rdlock(&rewrite_list->lock);
400 if (rewrite_list->enabled == FALSE) {
401 pthread_rwlock_unlock(&rewrite_list->lock);
406 for (rewrite = rewrite_list->rewrite; rewrite != NULL; rewrite = rewrite->next) {
407 if (rewrite->enabled == FALSE)
410 if (!(rewrite->which & flags))
413 if (connection->header != NULL) {
414 if (rewrite->he != NULL) {
415 ret = reg_exec(rewrite->he, connection->header->host);
419 if (rewrite->fe != NULL) {
420 ret = reg_exec(rewrite->fe, connection->header->file);
424 if (flags == REWRITE_BODY && rewrite->me != NULL && connection->rheader->content_type != NULL) {
425 ret = reg_exec(rewrite->me, connection->rheader->content_type);
428 } else if (rewrite->me != NULL) {
429 ret = reg_exec(rewrite->me, "");
434 if (rewrite->pe != NULL) {
440 reg_replace(filebuf, rewrite->pe, rewrite->replace);
441 } else if (rewrite->he != NULL || rewrite->fe != NULL || rewrite->me != NULL)
445 pthread_rwlock_unlock(&rewrite_list->lock);