39 */ |
39 */ |
40 void |
40 void |
41 process( char *line ) |
41 process( char *line ) |
42 { |
42 { |
43 parsed *p_request = parse_request( line ), *rule = NULL; |
43 parsed *p_request = parse_request( line ), *rule = NULL; |
44 parsed *results[ DB_RESULTS_MAX ] = { NULL }; /* array of response matches */ |
|
45 unsigned int rcount = 0; |
|
46 |
44 |
47 /* count lines in debugmode */ |
45 /* count lines in debugmode */ |
48 if ( v.debugmode > 2 ) v.timer.lines++; |
46 if ( v.debugmode > 2 ) v.timer.lines++; |
49 |
47 |
50 /* If request parsing failed, return a blank line to squid |
48 /* If request parsing failed, return a blank line to squid |
74 * what is present in the rule -- any missing parts just use the original |
72 * what is present in the rule -- any missing parts just use the original |
75 * URL element. (this way, you can rewrite just the host and leave the |
73 * URL element. (this way, you can rewrite just the host and leave the |
76 * path intact, or redir to https, for example.) |
74 * path intact, or redir to https, for example.) |
77 * |
75 * |
78 */ |
76 */ |
79 rcount = find_records( p_request->host, results ); |
77 rule = find_rule( p_request->host, p_request ); |
80 rule = find_matching_rule( results, rcount, p_request ); |
78 if ( rule == NULL ) rule = find_rule( p_request->tld, p_request ); |
|
79 if ( rule == NULL ) rule = find_rule( "*", p_request ); |
81 |
80 |
82 if ( rule == NULL ) { |
81 /* no matching rule still or whitelist rule? no need to rewrite anything. */ |
83 reset_results( results, rcount ); |
82 if ( rule == NULL || rule->wl ) { |
84 rcount = find_records( p_request->tld, results ); |
|
85 rule = find_matching_rule( results, rcount, p_request ); |
|
86 } |
|
87 |
|
88 if ( rule == NULL ) { |
|
89 reset_results( results, rcount ); |
|
90 rcount = find_records( "*", results ); |
|
91 rule = find_matching_rule( results, rcount, p_request ); |
|
92 } |
|
93 |
|
94 /* no matching rule still? no need to rewrite anything. */ |
|
95 if ( rule == NULL ) { |
|
96 out( "\n" ); |
83 out( "\n" ); |
97 } |
84 } |
98 /* otherwise, perform the rewrite */ |
85 /* otherwise, perform the rewrite. */ |
99 else { |
86 else { |
100 rewrite( p_request, rule ); |
87 rewrite( p_request, rule ); |
101 } |
88 } |
102 |
89 |
103 reset_results( results, rcount ); |
90 finish_parsed( rule ); |
104 finish_parsed( p_request ); |
91 finish_parsed( p_request ); |
105 return; |
92 return; |
106 } |
93 } |
107 |
94 |
108 |
95 |
124 return; |
111 return; |
125 } |
112 } |
126 |
113 |
127 |
114 |
128 /* |
115 /* |
129 * Search through a result set, and return the first |
116 * Compare a parsed +rule+ against the +request+. |
130 * matching path (or NULL). |
117 * Returns 1 on a match, 0 otherwise. |
131 * |
118 * |
132 */ |
119 */ |
133 parsed * |
120 unsigned short int |
134 find_matching_rule( parsed **results, unsigned int resultcount, parsed *p_request ) |
121 check_rule( parsed *rule, parsed *p_request ) |
135 { |
122 { |
136 unsigned int i = 0; |
|
137 int re_rv; |
123 int re_rv; |
138 regex_t re; |
124 regex_t re; |
139 char re_err[128]; |
125 char re_err[128]; |
140 parsed *rule = NULL; |
|
141 |
126 |
142 if ( resultcount == 0 || p_request->path == NULL ) return( NULL ); |
127 if ( rule == NULL || p_request->path == NULL ) return( 0 ); |
143 |
128 |
144 for ( i = 0; i < resultcount; i++ ) { |
129 /* quick comparison */ |
145 /* quick comparison */ |
130 if ( (strcasecmp( rule->path_re, p_request->path ) == 0) || |
146 if ( (strcasecmp( results[i]->path_re, p_request->path ) == 0) || |
131 (strcmp( rule->path_re, "*" ) == 0) ) { |
147 (strcmp( results[i]->path_re, "*" ) == 0) ) { |
132 debug( 4, LOC, "Rule match \"%s\" (non regexp)\n", rule->path_re ); |
148 debug( 4, LOC, "Rule %d match (non regexp)\n", i+1 ); |
133 return( 1 ); |
149 rule = results[i]; |
|
150 break; |
|
151 } |
|
152 |
|
153 /* compile the regexp */ |
|
154 if ( (re_rv = regcomp( &re, results[i]->path_re, REG_EXTENDED | REG_NOSUB )) != 0 ) { |
|
155 regerror( re_rv, &re, re_err, 128 ); |
|
156 debug( 4, LOC, "Invalid regex: \"%s\": %s\n", results[i]->path_re, re_err ); |
|
157 regfree( &re ); |
|
158 continue; |
|
159 } |
|
160 |
|
161 /* compare! */ |
|
162 if ( (regexec( &re, p_request->path, 0, NULL, 0 )) == 0 ) { |
|
163 debug( 4, LOC, "Rule %d match (regexp)\n", i+1 ); |
|
164 rule = results[i]; |
|
165 regfree( &re ); |
|
166 break; |
|
167 } |
|
168 } |
134 } |
169 |
135 |
170 return( rule ); |
136 /* compile the regexp */ |
|
137 if ( (re_rv = regcomp( &re, rule->path_re, REG_EXTENDED | REG_NOSUB )) != 0 ) { |
|
138 regerror( re_rv, &re, re_err, 128 ); |
|
139 debug( 4, LOC, "Invalid regex: \"%s\": %s\n", rule->path_re, re_err ); |
|
140 regfree( &re ); |
|
141 return( 0 ); |
|
142 } |
|
143 |
|
144 /* compare! */ |
|
145 if ( (regexec( &re, p_request->path, 0, NULL, 0 )) == 0 ) { |
|
146 debug( 4, LOC, "Rule match \"%s\" (regexp)\n", rule->path_re ); |
|
147 regfree( &re ); |
|
148 return( 1 ); |
|
149 } |
|
150 else { |
|
151 regfree( &re ); |
|
152 return( 0 ); |
|
153 } |
171 } |
154 } |
172 |
155 |
173 |
|
174 /* |
|
175 * Clear the results array and free memory. |
|
176 * |
|
177 */ |
|
178 void |
|
179 reset_results( parsed **results, unsigned int count ) |
|
180 { |
|
181 unsigned int i = 0; |
|
182 |
|
183 for ( ; i < count && i < DB_RESULTS_MAX; i++ ) finish_parsed( results[i] ); |
|
184 memset( results, 0, sizeof(results) ); |
|
185 |
|
186 return; |
|
187 } |
|
188 |
|