Skip to content
This repository was archived by the owner on Nov 6, 2022. It is now read-only.

Commit fd65b0f

Browse files
dolmenindutny
authored andcommitted
src: refactor method parsing
Use a switch and a macro to branch parsing of HTTP methods. Easier to read and much shorter. In this commit, the order of branches dispatching is the same as in the original code, to ease review. Reordering branches by descending frequency will improve speed too. PR-URL: #273 Reviewed-By: Fedor Indutny <fedor@indutny.com>
1 parent 678a9e2 commit fd65b0f

File tree

1 file changed

+31
-80
lines changed

1 file changed

+31
-80
lines changed

http_parser.c

Lines changed: 31 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,89 +1007,40 @@ size_t http_parser_execute (http_parser *parser,
10071007
UPDATE_STATE(s_req_spaces_before_url);
10081008
} else if (ch == matcher[parser->index]) {
10091009
; /* nada */
1010-
} else if (parser->method == HTTP_CONNECT) {
1011-
if (parser->index == 1 && ch == 'H') {
1012-
parser->method = HTTP_CHECKOUT;
1013-
} else if (parser->index == 2 && ch == 'P') {
1014-
parser->method = HTTP_COPY;
1015-
} else {
1016-
SET_ERRNO(HPE_INVALID_METHOD);
1017-
goto error;
1018-
}
1019-
} else if (parser->method == HTTP_MKCOL) {
1020-
if (parser->index == 1 && ch == 'O') {
1021-
parser->method = HTTP_MOVE;
1022-
} else if (parser->index == 1 && ch == 'E') {
1023-
parser->method = HTTP_MERGE;
1024-
} else if (parser->index == 1 && ch == '-') {
1025-
parser->method = HTTP_MSEARCH;
1026-
} else if (parser->index == 2 && ch == 'A') {
1027-
parser->method = HTTP_MKACTIVITY;
1028-
} else if (parser->index == 3 && ch == 'A') {
1029-
parser->method = HTTP_MKCALENDAR;
1030-
} else {
1031-
SET_ERRNO(HPE_INVALID_METHOD);
1032-
goto error;
1033-
}
1034-
} else if (parser->method == HTTP_SUBSCRIBE) {
1035-
if (parser->index == 1 && ch == 'E') {
1036-
parser->method = HTTP_SEARCH;
1037-
} else {
1038-
SET_ERRNO(HPE_INVALID_METHOD);
1039-
goto error;
1040-
}
1041-
} else if (parser->method == HTTP_REPORT) {
1042-
if (parser->index == 2 && ch == 'B') {
1043-
parser->method = HTTP_REBIND;
1044-
} else {
1045-
SET_ERRNO(HPE_INVALID_METHOD);
1046-
goto error;
1047-
}
1048-
} else if (parser->index == 1) {
1049-
if (parser->method == HTTP_POST) {
1050-
if (ch == 'R') {
1051-
parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */
1052-
} else if (ch == 'U') {
1053-
parser->method = HTTP_PUT; /* or HTTP_PURGE */
1054-
} else if (ch == 'A') {
1055-
parser->method = HTTP_PATCH;
1056-
} else {
1057-
SET_ERRNO(HPE_INVALID_METHOD);
1058-
goto error;
1059-
}
1060-
} else if (parser->method == HTTP_LOCK) {
1061-
if (ch == 'I') {
1062-
parser->method = HTTP_LINK;
1063-
} else {
1064-
SET_ERRNO(HPE_INVALID_METHOD);
1065-
goto error;
1066-
}
1067-
}
1068-
} else if (parser->index == 2) {
1069-
if (parser->method == HTTP_PUT) {
1070-
if (ch == 'R') {
1071-
parser->method = HTTP_PURGE;
1072-
} else {
1073-
SET_ERRNO(HPE_INVALID_METHOD);
1074-
goto error;
1075-
}
1076-
} else if (parser->method == HTTP_UNLOCK) {
1077-
if (ch == 'S') {
1078-
parser->method = HTTP_UNSUBSCRIBE;
1079-
} else if(ch == 'B') {
1080-
parser->method = HTTP_UNBIND;
1081-
} else {
1010+
} else if (IS_ALPHA(ch)) {
1011+
1012+
switch (parser->method << 16 | parser->index << 8 | ch) {
1013+
#define XX(meth, pos, ch, new_meth) \
1014+
case (HTTP_##meth << 16 | pos << 8 | ch): \
1015+
parser->method = HTTP_##new_meth; break;
1016+
1017+
XX(POST, 1, 'U', PUT)
1018+
XX(POST, 1, 'A', PATCH)
1019+
XX(CONNECT, 1, 'H', CHECKOUT)
1020+
XX(CONNECT, 2, 'P', COPY)
1021+
XX(MKCOL, 1, 'O', MOVE)
1022+
XX(MKCOL, 1, 'E', MERGE)
1023+
XX(MKCOL, 2, 'A', MKACTIVITY)
1024+
XX(MKCOL, 3, 'A', MKCALENDAR)
1025+
XX(SUBSCRIBE, 1, 'E', SEARCH)
1026+
XX(REPORT, 2, 'B', REBIND)
1027+
XX(POST, 1, 'R', PROPFIND)
1028+
XX(PROPFIND, 4, 'P', PROPPATCH)
1029+
XX(PUT, 2, 'R', PURGE)
1030+
XX(LOCK, 1, 'I', LINK)
1031+
XX(UNLOCK, 2, 'S', UNSUBSCRIBE)
1032+
XX(UNLOCK, 2, 'B', UNBIND)
1033+
XX(UNLOCK, 3, 'I', UNLINK)
1034+
#undef XX
1035+
1036+
default:
10821037
SET_ERRNO(HPE_INVALID_METHOD);
10831038
goto error;
1084-
}
1085-
} else {
1086-
SET_ERRNO(HPE_INVALID_METHOD);
1087-
goto error;
10881039
}
1089-
} else if (parser->index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') {
1090-
parser->method = HTTP_PROPPATCH;
1091-
} else if (parser->index == 3 && parser->method == HTTP_UNLOCK && ch == 'I') {
1092-
parser->method = HTTP_UNLINK;
1040+
} else if (ch == '-' &&
1041+
parser->index == 1 &&
1042+
parser->method == HTTP_MKCOL) {
1043+
parser->method = HTTP_MSEARCH;
10931044
} else {
10941045
SET_ERRNO(HPE_INVALID_METHOD);
10951046
goto error;

0 commit comments

Comments
 (0)