process.c
changeset 15 2706fc514dea
parent 14 51eb85ae4de4
child 16 e6a640ad2cc2
equal deleted inserted replaced
14:51eb85ae4de4 15:2706fc514dea
    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