MINOR: http: use http uri parser for scheme

Replace http_get_scheme by the http_uri_parser API. The new function is
renamed http_parse_scheme. A new http_uri_parser state is declared to
mark the scheme parsing as completed.
This commit is contained in:
Amaury Denoyelle 2021-07-06 10:52:58 +02:00
parent 89c68c8117
commit 8ac8cbfd72
4 changed files with 17 additions and 13 deletions

View File

@ -134,6 +134,7 @@ enum http_etag_type {
/* Indicates what elements have been parsed in a HTTP URI. */ /* Indicates what elements have been parsed in a HTTP URI. */
enum http_uri_parser_state { enum http_uri_parser_state {
URI_PARSER_STATE_BEFORE = 0, URI_PARSER_STATE_BEFORE = 0,
URI_PARSER_STATE_SCHEME_DONE,
}; };
/* HTTP URI format as described in rfc 7230 5.3. /* HTTP URI format as described in rfc 7230 5.3.

View File

@ -36,7 +36,7 @@ extern const uint8_t http_char_classes[256];
enum http_meth_t find_http_meth(const char *str, const int len); enum http_meth_t find_http_meth(const char *str, const int len);
int http_get_status_idx(unsigned int status); int http_get_status_idx(unsigned int status);
const char *http_get_reason(unsigned int status); const char *http_get_reason(unsigned int status);
struct ist http_get_scheme(const struct ist uri); struct ist http_parse_scheme(struct http_uri_parser *parser);
struct ist http_get_authority(const struct ist uri, int no_userinfo); struct ist http_get_authority(const struct ist uri, int no_userinfo);
struct ist http_get_path(const struct ist uri); struct ist http_get_path(const struct ist uri);
int http_header_match2(const char *hdr, const char *end, int http_header_match2(const char *hdr, const char *end,

View File

@ -470,25 +470,23 @@ const char *http_get_reason(unsigned int status)
/* Parse the uri and looks for the scheme. If not found, an empty ist is /* Parse the uri and looks for the scheme. If not found, an empty ist is
* returned. Otherwise, the ist pointing to the scheme is returned. * returned. Otherwise, the ist pointing to the scheme is returned.
*
* <parser> must have been initialized via http_uri_parser_init. See the
* related http_uri_parser documentation for the specific API usage.
*/ */
struct ist http_get_scheme(const struct ist uri) struct ist http_parse_scheme(struct http_uri_parser *parser)
{ {
const char *ptr, *start, *end; const char *ptr, *start, *end;
if (!uri.len) if (parser->state >= URI_PARSER_STATE_SCHEME_DONE)
goto not_found; goto not_found;
ptr = uri.ptr; if (parser->format != URI_PARSER_FORMAT_ABSURI_OR_AUTHORITY)
start = ptr;
end = ptr + uri.len;
/* RFC7230, par. 2.7 :
* Request-URI = "*" | absuri | abspath | authority
*/
if (*ptr == '*' || *ptr == '/')
goto not_found; goto not_found;
ptr = start = istptr(parser->uri);
end = istend(parser->uri);
if (isalpha((unsigned char)*ptr)) { if (isalpha((unsigned char)*ptr)) {
/* this is a scheme as described by RFC3986, par. 3.1, or only /* this is a scheme as described by RFC3986, par. 3.1, or only
* an authority (in case of a CONNECT method). * an authority (in case of a CONNECT method).
@ -512,9 +510,12 @@ struct ist http_get_scheme(const struct ist uri)
goto not_found; goto not_found;
} }
parser->uri = ist2(ptr, end - ptr);
parser->state = URI_PARSER_STATE_SCHEME_DONE;
return ist2(start, ptr - start); return ist2(start, ptr - start);
not_found: not_found:
parser->state = URI_PARSER_STATE_SCHEME_DONE;
return IST_NULL; return IST_NULL;
} }

View File

@ -1740,6 +1740,7 @@ int http_scheme_based_normalize(struct htx *htx)
struct htx_sl *sl; struct htx_sl *sl;
struct ist uri, scheme, authority, host, port; struct ist uri, scheme, authority, host, port;
char *start, *end, *ptr; char *start, *end, *ptr;
struct http_uri_parser parser;
sl = http_get_stline(htx); sl = http_get_stline(htx);
@ -1748,7 +1749,8 @@ int http_scheme_based_normalize(struct htx *htx)
uri = htx_sl_req_uri(sl); uri = htx_sl_req_uri(sl);
scheme = http_get_scheme(uri); parser = http_uri_parser_init(uri);
scheme = http_parse_scheme(&parser);
/* if no scheme found, no normalization to proceed */ /* if no scheme found, no normalization to proceed */
if (!isttest(scheme)) if (!isttest(scheme))
return 0; return 0;