static const char* parse_response(const char* buf, const char* buf_end, int* minor_version, int* status, const char** msg, size_t* msg_len, struct phr_header* headers, size_t* num_headers, size_t max_headers, int* ret) { /* parse "HTTP/1.x" */ if ((buf = parse_http_version(buf, buf_end, minor_version, ret)) == NULL) { return NULL; } /* skip space */ if (*buf++ != ' ') { *ret = -1; return NULL; } /* parse status code */ if ((buf = parse_int(buf, buf_end, status, ret)) == NULL) { return NULL; } /* skip space */ if (*buf++ != ' ') { *ret = -1; return NULL; } /* get message */ if ((buf = get_token_to_eol(buf, buf_end, msg, msg_len, ret)) == NULL) { return NULL; } return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret); }
static const char *parse_headers(const char *buf, const char *buf_end, struct phr_header *headers, size_t *num_headers, size_t max_headers, int *ret) { for (;; ++*num_headers) { CHECK_EOF(); if (*buf == '\015') { ++buf; EXPECT_CHAR('\012'); break; } else if (*buf == '\012') { ++buf; break; } if (*num_headers == max_headers) { *ret = -1; return NULL; } if (!(*num_headers != 0 && (*buf == ' ' || *buf == '\t'))) { if (!token_char_map[(unsigned char)*buf]) { *ret = -1; return NULL; } /* parsing name, but do not discard SP before colon, see * http://www.mozilla.org/security/announce/2006/mfsa2006-33.html */ headers[*num_headers].name = buf; static const char ALIGNED(16) ranges1[] = "::\x00\037"; int found; buf = findchar_fast(buf, buf_end, ranges1, sizeof(ranges1) - 1, &found); if (!found) { CHECK_EOF(); } while (1) { if (*buf == ':') { break; } else if (*buf < ' ') { *ret = -1; return NULL; } ++buf; CHECK_EOF(); } headers[*num_headers].name_len = buf - headers[*num_headers].name; ++buf; for (;; ++buf) { CHECK_EOF(); if (!(*buf == ' ' || *buf == '\t')) { break; } } } else { headers[*num_headers].name = NULL; headers[*num_headers].name_len = 0; } if ((buf = get_token_to_eol(buf, buf_end, &headers[*num_headers].value, &headers[*num_headers].value_len, ret)) == NULL) { return NULL; } }
static const char* parse_headers(const char* buf, const char* buf_end, struct phr_header* headers, size_t* num_headers, size_t max_headers, int* ret) { for (; ; ++*num_headers) { CHECK_EOF(); if (*buf == '\015') { ++buf; EXPECT_CHAR('\012'); break; } else if (*buf == '\012') { ++buf; break; } if (*num_headers == max_headers) { *ret = -1; return NULL; } if (*num_headers == 0 || ! (*buf == ' ' || *buf == '\t')) { /* parsing name, but do not discard SP before colon, see * http://www.mozilla.org/security/announce/2006/mfsa2006-33.html */ headers[*num_headers].name = buf; for (; ; ++buf) { CHECK_EOF(); if (*buf == ':') { break; } else if (*buf < ' ') { *ret = -1; return NULL; } } headers[*num_headers].name_len = buf - headers[*num_headers].name; ++buf; for (; ; ++buf) { CHECK_EOF(); if (! (*buf == ' ' || *buf == '\t')) { break; } } } else { headers[*num_headers].name = NULL; headers[*num_headers].name_len = 0; } if ((buf = get_token_to_eol(buf, buf_end, &headers[*num_headers].value, &headers[*num_headers].value_len, ret)) == NULL) { return NULL; } } return buf; }