In the source code, the httpd_got_request function is used for HTTP header detection.
This function does not detect the content of the header, but only the format of the header. The most obvious format detection is \ r \ n, space, Tab character, that is, HTTP protocol, each line in the header ends with \ r \ n. In the row, each word is separated by a space or a tab, which indicates that the request line has three words, whether the end Of the header ends with a blank line. That's all.
The following are several statuses used to check whether the format is valid.
/* Checks hc->read_buf to see whether a complete request has been read so far; ** either the first line has two words (an HTTP/0.9 request), or the first ** line has three words and there's a blank line present. ** ** hc->read_idx is how much has been read in; hc->checked_idx is how much we ** have checked so far; and hc->checked_state is the current state of the ** finite state machine. */int httpd_got_request(httpd_conn* hc) {char c;for (; hc->checked_idx < hc->read_idx; ++hc->checked_idx) {c = hc->read_buf[hc->checked_idx];switch (hc->checked_state) {case CHST_FIRSTWORD://the first word "GET"switch (c) {case ' ':case '\t':hc->checked_state = CHST_FIRSTWS;break;case '\012':case '\015':hc->checked_state = CHST_BOGUS;return GR_BAD_REQUEST;}break;case CHST_FIRSTWS:switch (c) {case ' ':case '\t':break;case '\012':case '\015':hc->checked_state = CHST_BOGUS;return GR_BAD_REQUEST;default:hc->checked_state = CHST_SECONDWORD;break;}break;case CHST_SECONDWORD:switch (c) {case ' ':case '\t':hc->checked_state = CHST_SECONDWS;break;case '\012':case '\015':/* The first line has only two words - an HTTP/0.9 request. */return GR_GOT_REQUEST;}break;case CHST_SECONDWS:switch (c) {case ' ':case '\t':break;case '\012':case '\015':hc->checked_state = CHST_BOGUS;return GR_BAD_REQUEST;default:hc->checked_state = CHST_THIRDWORD;break;}break;case CHST_THIRDWORD:switch (c) {case ' ':case '\t':hc->checked_state = CHST_THIRDWS;break;case '\012':hc->checked_state = CHST_LF;break;case '\015':hc->checked_state = CHST_CR;break;}break;case CHST_THIRDWS:switch (c) {case ' ':case '\t':break;case '\012':hc->checked_state = CHST_LF;break;case '\015':hc->checked_state = CHST_CR;break;default:hc->checked_state = CHST_BOGUS;return GR_BAD_REQUEST;}break;case CHST_LINE:switch (c) {case '\012':hc->checked_state = CHST_LF;break;case '\015':hc->checked_state = CHST_CR;break;}break;case CHST_LF:switch (c) {case '\012':/* Two newlines in a row - a blank line - end of request. */return GR_GOT_REQUEST;case '\015':hc->checked_state = CHST_CR;break;default:hc->checked_state = CHST_LINE;break;}break;case CHST_CR:switch (c) {case '\012':hc->checked_state = CHST_CRLF;break;case '\015':/* Two returns in a row - end of request. */return GR_GOT_REQUEST;default:hc->checked_state = CHST_LINE;break;}break;case CHST_CRLF:switch (c) {case '\012':/* Two newlines in a row - end of request. */return GR_GOT_REQUEST;case '\015':hc->checked_state = CHST_CRLFCR;break;default:hc->checked_state = CHST_LINE;break;}break;case CHST_CRLFCR:switch (c) {case '\012':case '\015':/* Two CRLFs or two CRs in a row - end of request. */return GR_GOT_REQUEST;default:hc->checked_state = CHST_LINE;break;}break;case CHST_BOGUS:return GR_BAD_REQUEST;}}return GR_NO_REQUEST;}