http-message-parser.c revision e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbe
/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "istream.h"
#include "http-parser.h"
#include "http-header.h"
#include "http-header-parser.h"
#include "http-date.h"
#include "http-transfer.h"
#include "http-message-parser.h"
#include <ctype.h>
{
if (hdr_limits != NULL)
}
{
}
{
} else {
}
} else {
}
}
{
/* HTTP-version = HTTP-name "/" DIGIT "." DIGIT
HTTP-name = %x48.54.54.50 ; "HTTP", case-sensitive
*/
if (size < 8)
return 0;
return -1;
}
return 1;
}
{
const unsigned char *data;
int ret;
return 1;
if (ret < 0) {
} else {
}
}
return ret;
}
return 1;
}
static int
{
const struct http_header_field *hdr;
struct http_parser hparser;
Section 3.2.2:
A sender MUST NOT generate multiple header fields with the same field
name in a message unless either the entire field value for that
header field is defined as a comma-separated list [i.e., #(values)]
or the header field is a well-known exception.
*/
switch (name[0]) {
case 'C': case 'c':
/* Connection: */
const char **opt_idx;
const char *option;
unsigned int num_tokens = 0;
/* Multiple Connection headers are allowed and combined into one */
/* Connection = 1#connection-option
connection-option = token
*/
for (;;) {
break;
num_tokens++;
}
return -1;
}
return 0;
}
/* Content-Length: */
return -1;
}
/* Content-Length = 1*DIGIT */
return -1;
}
return 0;
}
break;
case 'D': case 'd':
return -1;
}
/* Date = HTTP-date */
return 0;
}
break;
case 'L': case 'l':
/* FIXME: move this to response parser */
/* Location = URI-reference (not parsed here) */
return 0;
}
break;
case 'T': case 't':
/* Transfer-Encoding: */
/* Multiple Transfer-Encoding headers are allowed and combined into one */
/* Transfer-Encoding = 1#transfer-coding
transfer-coding = "chunked" / "compress" / "deflate" / "gzip"
/ transfer-extension
transfer-extension = token *( OWS ";" OWS transfer-parameter )
transfer-parameter = attribute BWS "=" BWS value
attribute = token
value = word
*/
for (;;) {
/* transfer-coding */
struct http_transfer_coding *coding;
bool parse_error;
/* *( OWS ";" OWS transfer-parameter ) */
parse_error = FALSE;
for (;;) {
struct http_transfer_param *param;
/* OWS ";" OWS */
break;
/* attribute */
parse_error = TRUE;
break;
}
/* BWS "=" BWS */
parse_error = TRUE;
break;
}
/* value */
parse_error = TRUE;
break;
}
}
if (parse_error)
break;
} else {
Appendix B:
For compatibility with legacy list rules, recipients SHOULD accept
empty list elements.
*/
}
break;
}
return -1;
}
return 0;
}
break;
default:
break;
}
return 0;
}
{
const unsigned char *field_data;
const char *field_name, *error;
int ret;
/* *( header-field CRLF ) CRLF */
if (field_name == NULL) {
/* EOH */
/* handle HTTP/1.0 persistence */
!msg->connection_close) {
const char *const *option;
break;
}
}
}
return 1;
}
return -1;
}
if (ret < 0) {
} else {
}
}
return ret;
}
{
const struct http_transfer_coding *coding;
bool chunked_last = FALSE;
chunked_last = TRUE;
const struct http_transfer_param *param =
"Unexpected parameter `%s' specified"
/* recoverable */
}
} else if (chunked_last) {
return -1;
/* recoverable */
}
}
if (chunked_last) {
} else if (!request) {
Section 3.3.3.:
If a Transfer-Encoding header field is present in a response and
the chunked transfer coding is not the final encoding, the
message body length is determined by reading the connection until
it is closed by the server.
*/
/* FIXME: enforce max payload size (relevant to http-client only) */
} else {
Section 3.3.3.:
If a Transfer-Encoding header field is present in a request and the
chunked transfer coding is not the final encoding, the message body
length cannot be determined reliably; the server MUST respond with
the 400 (Bad Request) status code and then close the connection.
*/
return -1;
}
Section 3.3.3.:
If a message is received with both a Transfer-Encoding and a
Content-Length header field, the Transfer-Encoding overrides the
Content-Length. Such a message might indicate an attempt to
perform request or response smuggling (bypass of security-related
checks on message routing or content) and thus ought to be
handled as an error. A sender MUST remove the received Content-
Length field prior to forwarding such a message downstream.
*/
if (parser->max_payload_size > 0
return -1;
}
/* Got explicit message size from Content-Length: header */
Section 3.3.3.:
If this is a request message and none of the above are true, then
the message body length is zero (no message body is present).
Otherwise, this is a response message without a declared message
body length, so the message body length is determined by the
number of octets received prior to the server closing the connection.
*/
/* FIXME: enforce max payload size (relevant to http-client only) */
}
return -1;
return 0;
}