Exemplo n.º 1
0
static int
http_parse_auth_param(struct http_parser *parser,
	const char **param_r, const char **value_r)
{
	const unsigned char *first = parser->cur, *end_token;
	int ret;

	/* auth-param     = token BWS "=" BWS ( token / quoted-string ) */

	/* token */
	if ((ret=http_parser_skip_token(parser)) <= 0) {
		parser->cur = first;
		return ret;
	}
	end_token = parser->cur;

	/* BWS "=" BWS */
	http_parse_ows(parser);
	if (parser->cur >= parser->end || *parser->cur != '=') {
		parser->cur = first;
		return 0;
	}
	parser->cur++;
	http_parse_ows(parser);

	/* ( token / quoted-string ) */
	if ((ret=http_parse_token_or_qstring(parser, value_r)) <= 0) {
		parser->cur = first;
		return ret;
	}

	*param_r = t_strndup(first, end_token - first);
	return 1;
}
Exemplo n.º 2
0
int http_parse_token_list_next(struct http_parser *parser,
	const char **token_r)
{
	/* http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-21;
	     Appendix B:

	   For compatibility with legacy list rules, recipients SHOULD accept
	   empty list elements.  In other words, consumers would follow the list
	   productions:

	   #element => [ ( "," / element ) *( OWS "," [ OWS element ] ) ]
	   1#element => *( "," OWS ) element *( OWS "," [ OWS element ] )
	*/

	for (;;) {	
		if (http_parse_token(parser, token_r) > 0)
			break;
		http_parse_ows(parser);
		if (parser->cur >= parser->end || parser->cur[0] != ',')
			return 0;
		parser->cur++;
		http_parse_ows(parser);
	}

	return 1;
}
static int
http_request_parse_expect_header(struct http_request_parser *parser,
	struct http_request *request, const struct http_header_field *hdr)
{
	struct http_message_parser *_parser = &parser->parser;
	struct http_parser hparser;
	bool parse_error = FALSE;
	unsigned int num_expectations = 0;

	/* Expect       = 1#expectation
	   expectation  = expect-name [ BWS "=" BWS expect-value ]
	                    *( OWS ";" [ OWS expect-param ] )
	   expect-param = expect-name [ BWS "=" BWS expect-value ]
	   expect-name  = token
	   expect-value = token / quoted-string
	 */
	http_parser_init(&hparser, (const unsigned char *)hdr->value, hdr->size);
	while (!parse_error) {
		const char *expect_name, *expect_value;

		/* expect-name */
		if (http_parse_token(&hparser, &expect_name) > 0) {
			num_expectations++;
			if (strcasecmp(expect_name, "100-continue") == 0) {
				request->expect_100_continue = TRUE;
			} else {
				/* http://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-23
				     Section 5.1.1:

				   If all received Expect header field(s) are syntactically valid but
				   contain an expectation that the recipient does not understand or
				   cannot comply with, the recipient MUST respond with a 417
				   (Expectation Failed) status code.  A recipient of a syntactically
				   invalid Expectation header field MUST respond with a 4xx status code
				   other than 417.

				   --> Must check rest of expect header syntax before returning error.
				 */
				if (parser->error_code == HTTP_REQUEST_PARSE_ERROR_NONE) {
					parser->error_code = HTTP_REQUEST_PARSE_ERROR_EXPECTATION_FAILED;
					_parser->error = t_strdup_printf
						("Unknown Expectation `%s'", expect_name);
				}
			}

			/* BWS "=" BWS */
			http_parse_ows(&hparser);
			if (hparser.cur >= hparser.end)
				break;
			
			if (*hparser.cur == '=') {
				hparser.cur++;
				http_parse_ows(&hparser);

				/* value */
				if (http_parse_word(&hparser, &expect_value) <= 0) {
					parse_error = TRUE;
					break;
				}
		
				if (parser->error_code == HTTP_REQUEST_PARSE_ERROR_NONE) {
					parser->error_code = HTTP_REQUEST_PARSE_ERROR_EXPECTATION_FAILED;
					_parser->error = t_strdup_printf
						("Expectation `%s' has unexpected value", expect_name);
				}
			}

			/* *( OWS ";" [ OWS expect-param ] ) */
			while (!parse_error) {
				const char *attribute, *value;

				/* OWS ";" */
				http_parse_ows(&hparser);
				if (hparser.cur >= hparser.end || *hparser.cur != ';')
					break;
				hparser.cur++;
				http_parse_ows(&hparser);

				/* expect-param */
				if (http_parse_token(&hparser, &attribute) <= 0) {
					parse_error = TRUE;
					break;
				}

				/* BWS "=" BWS */
				http_parse_ows(&hparser);
				if (hparser.cur >= hparser.end || *hparser.cur != '=') {
					parse_error = TRUE;
					break;
				}
				hparser.cur++;
				http_parse_ows(&hparser);

				/* value */
				if (http_parse_word(&hparser, &value) <= 0) {
					parse_error = TRUE;
					break;
				}

				if (parser->error_code == HTTP_REQUEST_PARSE_ERROR_NONE) {
					parser->error_code = HTTP_REQUEST_PARSE_ERROR_EXPECTATION_FAILED;
					_parser->error = t_strdup_printf
						("Expectation `%s' has unknown parameter `'%s'",
							expect_name, attribute);
				}
			}
			if (parse_error)
				break;		
		}
		http_parse_ows(&hparser);
		if (hparser.cur >= hparser.end || *hparser.cur != ',')
			break;
		hparser.cur++;
		http_parse_ows(&hparser);
	}

	if (parse_error || hparser.cur < hparser.end) {
		parser->error_code = HTTP_REQUEST_PARSE_ERROR_BAD_REQUEST;
		_parser->error = "Invalid Expect header";
		return -1;
	}

	if (parser->error_code != HTTP_REQUEST_PARSE_ERROR_NONE)
		return -1;

	if (num_expectations == 0) {
		parser->error_code = HTTP_REQUEST_PARSE_ERROR_BAD_REQUEST;
		_parser->error = "Empty Expect header";
		return -1;
	}
	return 0;
}
Exemplo n.º 4
0
static int
http_request_parse_expect_header(struct http_request_parser *parser,
	struct http_request *request, const struct http_header_field *hdr)
{
	struct http_message_parser *_parser = &parser->parser;
	struct http_parser hparser;
	bool parse_error = FALSE;
	unsigned int num_expectations = 0;

	/* RFC 7231, Section 5.1.1:

	   Expect  = "100-continue"
	 */
	// FIXME: simplify; RFC 7231 discarded Expect extension mechanism
	http_parser_init(&hparser, (const unsigned char *)hdr->value, hdr->size);
	while (!parse_error) {
		const char *expect_name, *expect_value;

		/* expect-name */
		if (http_parse_token(&hparser, &expect_name) > 0) {
			num_expectations++;
			if (strcasecmp(expect_name, "100-continue") == 0) {
				request->expect_100_continue = TRUE;
			} else {
				if (parser->error_code == HTTP_REQUEST_PARSE_ERROR_NONE) {
					parser->error_code = HTTP_REQUEST_PARSE_ERROR_EXPECTATION_FAILED;
					_parser->error = t_strdup_printf
						("Unknown Expectation `%s'", expect_name);
				}
			}

			/* BWS "=" BWS */
			http_parse_ows(&hparser);
			if (hparser.cur >= hparser.end)
				break;
			
			if (*hparser.cur == '=') {
				hparser.cur++;
				http_parse_ows(&hparser);

				/* value */
				if (http_parse_token_or_qstring(&hparser, &expect_value) <= 0) {
					parse_error = TRUE;
					break;
				}
		
				if (parser->error_code == HTTP_REQUEST_PARSE_ERROR_NONE) {
					parser->error_code = HTTP_REQUEST_PARSE_ERROR_EXPECTATION_FAILED;
					_parser->error = t_strdup_printf
						("Expectation `%s' has unexpected value", expect_name);
				}
			}

			/* *( OWS ";" [ OWS expect-param ] ) */
			while (!parse_error) {
				const char *attribute, *value;

				/* OWS ";" */
				http_parse_ows(&hparser);
				if (hparser.cur >= hparser.end || *hparser.cur != ';')
					break;
				hparser.cur++;
				http_parse_ows(&hparser);

				/* expect-param */
				if (http_parse_token(&hparser, &attribute) <= 0) {
					parse_error = TRUE;
					break;
				}

				/* BWS "=" BWS */
				http_parse_ows(&hparser);
				if (hparser.cur >= hparser.end || *hparser.cur != '=') {
					parse_error = TRUE;
					break;
				}
				hparser.cur++;
				http_parse_ows(&hparser);

				/* value */
				if (http_parse_token_or_qstring(&hparser, &value) <= 0) {
					parse_error = TRUE;
					break;
				}

				if (parser->error_code == HTTP_REQUEST_PARSE_ERROR_NONE) {
					parser->error_code = HTTP_REQUEST_PARSE_ERROR_EXPECTATION_FAILED;
					_parser->error = t_strdup_printf
						("Expectation `%s' has unknown parameter `'%s'",
							expect_name, attribute);
				}
			}
			if (parse_error)
				break;		
		}
		http_parse_ows(&hparser);
		if (hparser.cur >= hparser.end || *hparser.cur != ',')
			break;
		hparser.cur++;
		http_parse_ows(&hparser);
	}

	if (parse_error || hparser.cur < hparser.end) {
		parser->error_code = HTTP_REQUEST_PARSE_ERROR_BAD_REQUEST;
		_parser->error = "Invalid Expect header";
		return -1;
	}

	if (parser->error_code != HTTP_REQUEST_PARSE_ERROR_NONE)
		return -1;

	if (num_expectations == 0) {
		parser->error_code = HTTP_REQUEST_PARSE_ERROR_BAD_REQUEST;
		_parser->error = "Empty Expect header";
		return -1;
	}
	return 0;
}