if (debug) log_d("read_connection: %d %d %d %d", fd, p->end - p->floor, i, nr);
static void read_connection(struct connection *cn){	int i, nr, fd;	char c;	struct pool *p;	char state;	p = cn->input;	state = p->state;	fd = cn->fd;	i = p->ceiling - p->end;	if (i == 0) {		log_d("input buffer full");		set_connection_state(cn, HC_CLOSING);		return;	}	nr = recv(fd, p->end, i, MSG_PEEK);	if (nr == -1) {		switch (errno) {		default:			log_d("error peeking from %s[%hu]", inet_ntoa(cn->peer.sin_addr), ntohs(cn->peer.sin_port));			lerror("recv");		case ECONNRESET:		case EPIPE:			set_connection_state(cn, HC_CLOSING);		case EAGAIN:			return;		}	}	if (nr == 0) {		set_connection_state(cn, HC_CLOSING);		return;	}	i = 0;	while (i < nr && state < 8) {		c = p->end[i++];		if (c == 0) {			log_d("read_connection: NUL in headers");			set_connection_state(cn, HC_CLOSING);			return;		}		switch (state) {		case 0:			switch (c) {			default:				state = 1;				break;			case '\r':			case '\n':				break;			case ' ':			case '\t':				state = 2;				break;			}			if (state)				if (cn->connection_state == HC_WAITING) {					gettimeofday(&cn->itv, 0);					set_connection_state(cn, HC_READING);				}			break;		case 1:			switch (c) {			default:				break;			case ' ':			case '\t':				state = 2;				break;			case '\r':				state = 3;				break;			case '\n':				state = 8;				break;			}			break;		case 2:			switch (c) {			case 'H':				state = 4;				break;			default:				state = 1;				break;			case ' ':			case '\t':				break;			case '\r':				state = 3;				break;			case '\n':				state = 8;				break;			}			break;		case 3:			switch (c) {			case '\n':				state = 8;				break;			default:				state = 1;				break;			case ' ':			case '\t':				state = 2;				break;			case '\r':				break;			}			break;		case 4:			switch (c) {			case '\r':				state = 5;				break;			case '\n':				state = 6;				break;			}			break;		case 5:			switch (c) {			default:				state = 4;			case '\r':				break;			case '\n':				state = 6;				break;			}			break;		case 6:			switch (c) {			case '\r':				state = 7;				break;			case '\n':				state = 8;				break;			default:				state = 4;				break;			}			break;		case 7:			switch (c) {			default:				state = 4;			case '\r':				break;			case '\n':				state = 8;				break;			}			break;		}	}	nr = recv(fd, p->end, i, 0);	if (nr != i) {		if (nr == -1) {			log_d("error reading from %s[%hu]", inet_ntoa(cn->peer.sin_addr), ntohs(cn->peer.sin_port));			lerror("recv");		} else {			cn->nread += nr;			log_d("read_connection: %d != %d!", nr, i);		}		set_connection_state(cn, HC_CLOSING);		return;	}	cn->nread += nr;	p->end += i;	p->state = state;	cn->t = current_time;	if (state == 8) {		if (process_request(cn->r) == -1) {			if (cn->connection_state != HC_FORKED)				set_connection_state(cn, HC_CLOSING);			return;		}		cn->left = cn->r->content_length;		if (fill_connection(cn) == -1) {			set_connection_state(cn, HC_CLOSING);			return;		}		set_connection_state(cn, HC_WRITING);	}}