src/proto_http.c
static int http_forward_trailers(struct http_msg *msg)
{
	const struct buffer *buf = msg->chn->buf;

	/* we have msg->next which points to next line. Look for CRLF. */
	while (1) {
		const char *p1 = NULL, *p2 = NULL;
		const char *ptr = b_ptr(buf, msg->next);
		const char *stop = bi_end(buf);
		int bytes;

		/* scan current line and stop at LF or CRLF */
		while (1) {
			if (ptr == stop)
				return 0;

			if (*ptr == '\n') {
				if (!p1)
					p1 = ptr;
				p2 = ptr;
				break;
			}

			if (*ptr == '\r') {
				if (p1) {
					msg->err_pos = buffer_count(buf, buf->p, ptr);
					return -1;
				}
				p1 = ptr;
			}

			ptr++;
			if (ptr >= buf->data + buf->size)
				ptr = buf->data;
		}

		/* after LF; point to beginning of next line */
		p2++;
		if (p2 >= buf->data + buf->size)
			p2 = buf->data;

		bytes = p2 - b_ptr(buf, msg->next);
		if (bytes < 0)
			bytes += buf->size;

		/* schedule this line for forwarding */
		msg->sov += bytes;
		if (msg->sov >= buf->size)
			msg->sov -= buf->size;

		if (p1 == b_ptr(buf, msg->next)) {
			/* LF/CRLF at beginning of line => end of trailers at p2.
			 * Everything was scheduled for forwarding, there's nothing
			 * left from this message.
			 */
			msg->next = buffer_count(buf, buf->p, p2);
			msg->msg_state = HTTP_MSG_DONE;
			return 1;
		}
		/* OK, next line then */
		msg->next = buffer_count(buf, buf->p, p2);
	}
}
/* This function skips trailers in the buffer associated with HTTP
 * message <msg>. The first visited position is msg->next. If the end of
 * the trailers is found, it is automatically scheduled to be forwarded,
 * msg->msg_state switches to HTTP_MSG_DONE, and the function returns >0.
 * If not enough data are available, the function does not change anything
 * except maybe msg->next and msg->sov if it could parse some lines, and returns
 * zero. If a parse error is encountered, the function returns < 0 and does not
 * change anything except maybe msg->next and msg->sov. Note that the message
 * must already be in HTTP_MSG_TRAILERS state before calling this function,
 * which implies that all non-trailers data have already been scheduled for
 * forwarding, and that the difference between msg->sol and msg->sov exactly
 * matches the length of trailers already parsed and not forwarded. It is also
 * important to note that this function is designed to be able to parse wrapped
 * headers at end of buffer.
 */
This function skips trailers in the buffer associated with HTTP
message . The first visited position is msg->next. If the end of
the trailers is found, it is automatically scheduled to be forwarded,
msg->msg_state switches to HTTP_MSG_DONE, and the function returns >0.
If not enough data are available, the function does not change anything
except maybe msg->next and msg->sov if it could parse some lines, and returns
zero. If a parse error is encountered, the function returns < 0 and does not
change anything except maybe msg->next and msg->sov. Note that the message
must already be in HTTP_MSG_TRAILERS state before calling this function,
which implies that all non-trailers data have already been scheduled for
forwarding, and that the difference between msg->sol and msg->sov exactly
matches the length of trailers already parsed and not forwarded. It is also
important to note that this function is designed to be able to parse wrapped
headers at end of buffer.
This function skips trailers in the buffer associated with HTTP message . The first visited position is msg - > next . If the end of the trailers is found it is automatically scheduled to be forwarded msg - > msg_state switches to HTTP_MSG_DONE and the function returns > 0 . If not enough data are available the function does not change anything except maybe msg - > next and msg - > sov if it could parse some lines and returns zero . If a parse error is encountered the function returns < 0 and does not change anything except maybe msg - > next and msg - > sov . Note that the message must already be in HTTP_MSG_TRAILERS state before calling this function which implies that all non - trailers data have already been scheduled for forwarding and that the difference between msg - > sol and msg - > sov exactly matches the length of trailers already parsed and not forwarded . It is also important to note that this function is designed to be able to parse wrapped headers at end of buffer .
static int http_forward_trailers(struct http_msg *msg)
{
	const struct buffer *buf = msg->chn->buf;
	while (1) {
		const char *p1 = NULL, *p2 = NULL;
		const char *ptr = b_ptr(buf, msg->next);
		const char *stop = bi_end(buf);
		int bytes;
		while (1) {
			if (ptr == stop)
				return 0;
			if (*ptr == '\n') {
				if (!p1)
					p1 = ptr;
				p2 = ptr;
				break;
			}
			if (*ptr == '\r') {
				if (p1) {
					msg->err_pos = buffer_count(buf, buf->p, ptr);
					return -1;
				}
				p1 = ptr;
			}
			ptr++;
			if (ptr >= buf->data + buf->size)
				ptr = buf->data;
		}
		p2++;
		if (p2 >= buf->data + buf->size)
			p2 = buf->data;
		bytes = p2 - b_ptr(buf, msg->next);
		if (bytes < 0)
			bytes += buf->size;
		msg->sov += bytes;
		if (msg->sov >= buf->size)
			msg->sov -= buf->size;
		if (p1 == b_ptr(buf, msg->next)) {
			msg->next = buffer_count(buf, buf->p, p2);
			msg->msg_state = HTTP_MSG_DONE;
			return 1;
		}
		msg->next = buffer_count(buf, buf->p, p2);
	}
}
static int http_forward_trailers ( struct http_msg * msg ) { const struct buffer * buf = msg -> chn -> buf ; while ( 1 ) { const char * p1 = NULL , * p2 = NULL ; const char * ptr = b_ptr ( buf , msg -> next ) ; const char * stop = bi_end ( buf ) ; int bytes ; while ( 1 ) { if ( ptr == stop ) return 0 ; if ( * ptr == ' \n ' ) { if ( ! p1 ) p1 = ptr ; p2 = ptr ; break ; } if ( * ptr == ' \r ' ) { if ( p1 ) { msg -> err_pos = buffer_count ( buf , buf -> p , ptr ) ; return -1 ; } p1 = ptr ; } ptr ++ ; if ( ptr >= buf -> data + buf -> size ) ptr = buf -> data ; } p2 ++ ; if ( p2 >= buf -> data + buf -> size ) p2 = buf -> data ; bytes = p2 - b_ptr ( buf , msg -> next ) ; if ( bytes < 0 ) bytes += buf -> size ; msg -> sov += bytes ; if ( msg -> sov >= buf -> size ) msg -> sov -= buf -> size ; if ( p1 == b_ptr ( buf , msg -> next ) ) { msg -> next = buffer_count ( buf , buf -> p , p2 ) ; msg -> msg_state = HTTP_MSG_DONE ; return 1 ; } msg -> next = buffer_count ( buf , buf -> p , p2 ) ; } }
This function skips trailers in the buffer associated with HTTP
 message <msg>.
This function skips trailers in the buffer associated with HTTP message <msg > .
/* we have msg->next which points to next line. Look for CRLF. */ /* scan current line and stop at LF or CRLF */ /* after LF; point to beginning of next line */ /* schedule this line for forwarding */ /* LF/CRLF at beginning of line => end of trailers at p2.
			 * Everything was scheduled for forwarding, there's nothing
			 * left from this message.
			 */ /* OK, next line then */