src/proto_http.c
int apply_filter_to_req_line(struct session *t, struct channel *req, struct hdr_exp *exp)
{
	char term;
	char *cur_ptr, *cur_end;
	int done;
	struct http_txn *txn = &t->txn;
	int delta;

	if (unlikely(txn->flags & (TX_CLDENY | TX_CLTARPIT)))
		return 1;
	else if (unlikely(txn->flags & TX_CLALLOW) &&
		 (exp->action == ACT_ALLOW ||
		  exp->action == ACT_DENY ||
		  exp->action == ACT_TARPIT))
		return 0;
	else if (exp->action == ACT_REMOVE)
		return 0;

	done = 0;

	cur_ptr = req->buf->p;
	cur_end = cur_ptr + txn->req.sl.rq.l;

	/* Now we have the request line between cur_ptr and cur_end */

	/* The annoying part is that pattern matching needs
	 * that we modify the contents to null-terminate all
	 * strings before testing them.
	 */

	term = *cur_end;
	*cur_end = '\0';

	if (regexec(exp->preg, cur_ptr, MAX_MATCH, pmatch, 0) == 0) {
		switch (exp->action) {
		case ACT_SETBE:
			/* It is not possible to jump a second time.
			 * FIXME: should we return an HTTP/500 here so that
			 * the admin knows there's a problem ?
			 */
			if (t->be != t->fe)
				break;

			/* Swithing Proxy */
			session_set_backend(t, (struct proxy *)exp->replace);
			done = 1;
			break;

		case ACT_ALLOW:
			txn->flags |= TX_CLALLOW;
			done = 1;
			break;

		case ACT_DENY:
			txn->flags |= TX_CLDENY;

			t->fe->fe_counters.denied_req++;
			if (t->fe != t->be)
				t->be->be_counters.denied_req++;
			if (t->listener->counters)
				t->listener->counters->denied_req++;

			done = 1;
			break;

		case ACT_TARPIT:
			txn->flags |= TX_CLTARPIT;

			t->fe->fe_counters.denied_req++;
			if (t->fe != t->be)
				t->be->be_counters.denied_req++;
			if (t->listener->counters)
				t->listener->counters->denied_req++;

			done = 1;
			break;

		case ACT_REPLACE:
			*cur_end = term; /* restore the string terminator */
			trash.len = exp_replace(trash.str, cur_ptr, exp->replace, pmatch);
			delta = buffer_replace2(req->buf, cur_ptr, cur_end, trash.str, trash.len);
			/* FIXME: if the user adds a newline in the replacement, the
			 * index will not be recalculated for now, and the new line
			 * will not be counted as a new header.
			 */

			http_msg_move_end(&txn->req, delta);
			cur_end += delta;
			cur_end = (char *)http_parse_reqline(&txn->req,
							     HTTP_MSG_RQMETH,
							     cur_ptr, cur_end + 1,
							     NULL, NULL);
			if (unlikely(!cur_end))
				return -1;

			/* we have a full request and we know that we have either a CR
			 * or an LF at <ptr>.
			 */
			txn->meth = find_http_meth(cur_ptr, txn->req.sl.rq.m_l);
			hdr_idx_set_start(&txn->hdr_idx, txn->req.sl.rq.l, *cur_end == '\r');
			/* there is no point trying this regex on headers */
			return 1;
		}
	}
	*cur_end = term; /* restore the string terminator */
	return done;
}
/* Apply the filter to the request line.
 * Returns 0 if nothing has been done, 1 if the filter has been applied,
 * or -1 if a replacement resulted in an invalid request line.
 * Since it can manage the switch to another backend, it updates the per-proxy
 * DENY stats.
 */
Apply the filter to the request line.
Returns 0 if nothing has been done, 1 if the filter has been applied,
or -1 if a replacement resulted in an invalid request line.
Since it can manage the switch to another backend, it updates the per-proxy
DENY stats.
Apply the filter to the request line . Returns 0 if nothing has been done 1 if the filter has been applied or - 1 if a replacement resulted in an invalid request line . Since it can manage the switch to another backend it updates the per - proxy DENY stats .
int apply_filter_to_req_line(struct session *t, struct channel *req, struct hdr_exp *exp)
{
	char term;
	char *cur_ptr, *cur_end;
	int done;
	struct http_txn *txn = &t->txn;
	int delta;
	if (unlikely(txn->flags & (TX_CLDENY | TX_CLTARPIT)))
		return 1;
	else if (unlikely(txn->flags & TX_CLALLOW) &&
		 (exp->action == ACT_ALLOW ||
		  exp->action == ACT_DENY ||
		  exp->action == ACT_TARPIT))
		return 0;
	else if (exp->action == ACT_REMOVE)
		return 0;
	done = 0;
	cur_ptr = req->buf->p;
	cur_end = cur_ptr + txn->req.sl.rq.l;
	term = *cur_end;
	*cur_end = '\0';
	if (regexec(exp->preg, cur_ptr, MAX_MATCH, pmatch, 0) == 0) {
		switch (exp->action) {
		case ACT_SETBE:
			if (t->be != t->fe)
				break;
			session_set_backend(t, (struct proxy *)exp->replace);
			done = 1;
			break;
		case ACT_ALLOW:
			txn->flags |= TX_CLALLOW;
			done = 1;
			break;
		case ACT_DENY:
			txn->flags |= TX_CLDENY;
			t->fe->fe_counters.denied_req++;
			if (t->fe != t->be)
				t->be->be_counters.denied_req++;
			if (t->listener->counters)
				t->listener->counters->denied_req++;
			done = 1;
			break;
		case ACT_TARPIT:
			txn->flags |= TX_CLTARPIT;
			t->fe->fe_counters.denied_req++;
			if (t->fe != t->be)
				t->be->be_counters.denied_req++;
			if (t->listener->counters)
				t->listener->counters->denied_req++;
			done = 1;
			break;
		case ACT_REPLACE:
			*cur_end = term; 
			trash.len = exp_replace(trash.str, cur_ptr, exp->replace, pmatch);
			delta = buffer_replace2(req->buf, cur_ptr, cur_end, trash.str, trash.len);
			http_msg_move_end(&txn->req, delta);
			cur_end += delta;
			cur_end = (char *)http_parse_reqline(&txn->req,
							     HTTP_MSG_RQMETH,
							     cur_ptr, cur_end + 1,
							     NULL, NULL);
			if (unlikely(!cur_end))
				return -1;
			txn->meth = find_http_meth(cur_ptr, txn->req.sl.rq.m_l);
			hdr_idx_set_start(&txn->hdr_idx, txn->req.sl.rq.l, *cur_end == '\r');
			return 1;
		}
	}
	*cur_end = term; 
	return done;
}
int apply_filter_to_req_line ( struct session * t , struct channel * req , struct hdr_exp * exp ) { char term ; char * cur_ptr , * cur_end ; int done ; struct http_txn * txn = & t -> txn ; int delta ; if ( unlikely ( txn -> flags & ( TX_CLDENY | TX_CLTARPIT ) ) ) return 1 ; else if ( unlikely ( txn -> flags & TX_CLALLOW ) && ( exp -> action == ACT_ALLOW || exp -> action == ACT_DENY || exp -> action == ACT_TARPIT ) ) return 0 ; else if ( exp -> action == ACT_REMOVE ) return 0 ; done = 0 ; cur_ptr = req -> buf -> p ; cur_end = cur_ptr + txn -> req . sl . rq . l ; term = * cur_end ; * cur_end = ' \0 ' ; if ( regexec ( exp -> preg , cur_ptr , MAX_MATCH , pmatch , 0 ) == 0 ) { switch ( exp -> action ) { case ACT_SETBE : if ( t -> be != t -> fe ) break ; session_set_backend ( t , ( struct proxy * ) exp -> replace ) ; done = 1 ; break ; case ACT_ALLOW : txn -> flags |= TX_CLALLOW ; done = 1 ; break ; case ACT_DENY : txn -> flags |= TX_CLDENY ; t -> fe -> fe_counters . denied_req ++ ; if ( t -> fe != t -> be ) t -> be -> be_counters . denied_req ++ ; if ( t -> listener -> counters ) t -> listener -> counters -> denied_req ++ ; done = 1 ; break ; case ACT_TARPIT : txn -> flags |= TX_CLTARPIT ; t -> fe -> fe_counters . denied_req ++ ; if ( t -> fe != t -> be ) t -> be -> be_counters . denied_req ++ ; if ( t -> listener -> counters ) t -> listener -> counters -> denied_req ++ ; done = 1 ; break ; case ACT_REPLACE : * cur_end = term ; trash . len = exp_replace ( trash . str , cur_ptr , exp -> replace , pmatch ) ; delta = buffer_replace2 ( req -> buf , cur_ptr , cur_end , trash . str , trash . len ) ; http_msg_move_end ( & txn -> req , delta ) ; cur_end += delta ; cur_end = ( char * ) http_parse_reqline ( & txn -> req , HTTP_MSG_RQMETH , cur_ptr , cur_end + 1 , NULL , NULL ) ; if ( unlikely ( ! cur_end ) ) return -1 ; txn -> meth = find_http_meth ( cur_ptr , txn -> req . sl . rq . m_l ) ; hdr_idx_set_start ( & txn -> hdr_idx , txn -> req . sl . rq . l , * cur_end == ' \r ' ) ; return 1 ; } } * cur_end = term ; return done ; }
Apply the filter to the request line.
Apply the filter to the request line .
/* Now we have the request line between cur_ptr and cur_end */ /* The annoying part is that pattern matching needs
	 * that we modify the contents to null-terminate all
	 * strings before testing them.
	 */ /* It is not possible to jump a second time.
			 * FIXME: should we return an HTTP/500 here so that
			 * the admin knows there's a problem ?
			 */ /* Swithing Proxy */ /* restore the string terminator */ /* FIXME: if the user adds a newline in the replacement, the
			 * index will not be recalculated for now, and the new line
			 * will not be counted as a new header.
			 */ /* we have a full request and we know that we have either a CR
			 * or an LF at <ptr>.
			 */ /* there is no point trying this regex on headers */ /* restore the string terminator */