int httpd_got_request()

in netutils/thttpd/libhttpd.c [2443:2651]


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:
          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;
}