mturk 2004/12/16 00:38:05 Modified: jk/native/common jk_ajp_common.c Log: Backport method parsing from ajp project. It's more efficient then previous. Revision Changes Path 1.68 +173 -95 jakarta-tomcat-connectors/jk/native/common/jk_ajp_common.c Index: jk_ajp_common.c =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/common/jk_ajp_common.c,v retrieving revision 1.67 retrieving revision 1.68 diff -u -r1.67 -r1.68 --- jk_ajp_common.c 15 Dec 2004 20:31:16 -0000 1.67 +++ jk_ajp_common.c 16 Dec 2004 08:38:05 -0000 1.68 @@ -72,106 +72,183 @@ { const char *rc = NULL; sc = sc & 0X00FF; - if(sc <= SC_RES_HEADERS_NUM && sc > 0) { + if (sc <= SC_RES_HEADERS_NUM && sc > 0) { rc = response_trans_headers[sc - 1]; } return rc; } +#define UNKNOWN_METHOD (-1) -static int sc_for_req_method(const char *method, unsigned char *sc) +static int sc_for_req_method(const char *method, size_t len) { - int rc = JK_TRUE; - if (0 == strcmp(method, "GET")) { - *sc = SC_M_GET; - } - else if (0 == strcmp(method, "POST")) { - *sc = SC_M_POST; - } - else if (0 == strcmp(method, "HEAD")) { - *sc = SC_M_HEAD; - } - else if (0 == strcmp(method, "PUT")) { - *sc = SC_M_PUT; - } - else if (0 == strcmp(method, "DELETE")) { - *sc = SC_M_DELETE; - } - else if (0 == strcmp(method, "OPTIONS")) { - *sc = SC_M_OPTIONS; - } - else if (0 == strcmp(method, "TRACE")) { - *sc = SC_M_TRACE; - } - else if (0 == strcmp(method, "PROPFIND")) { - *sc = SC_M_PROPFIND; - } - else if (0 == strcmp(method, "PROPPATCH")) { - *sc = SC_M_PROPPATCH; - } - else if (0 == strcmp(method, "MKCOL")) { - *sc = SC_M_MKCOL; - } - else if (0 == strcmp(method, "COPY")) { - *sc = SC_M_COPY; - } - else if (0 == strcmp(method, "MOVE")) { - *sc = SC_M_MOVE; - } - else if (0 == strcmp(method, "LOCK")) { - *sc = SC_M_LOCK; - } - else if (0 == strcmp(method, "UNLOCK")) { - *sc = SC_M_UNLOCK; - } - else if (0 == strcmp(method, "ACL")) { - *sc = SC_M_ACL; - } - else if (0 == strcmp(method, "REPORT")) { - *sc = SC_M_REPORT; - } - else if (0 == strcmp(method, "VERSION-CONTROL")) { - *sc = SC_M_VERSION_CONTROL; - } - else if (0 == strcmp(method, "CHECKIN")) { - *sc = SC_M_CHECKIN; - } - else if (0 == strcmp(method, "CHECKOUT")) { - *sc = SC_M_CHECKOUT; - } - else if (0 == strcmp(method, "UNCHECKOUT")) { - *sc = SC_M_UNCHECKOUT; - } - else if (0 == strcmp(method, "SEARCH")) { - *sc = SC_M_SEARCH; - } - else if (0 == strcmp(method, "MKWORKSPACE")) { - *sc = SC_M_MKWORKSPACE; - } - else if (0 == strcmp(method, "UPDATE")) { - *sc = SC_M_UPDATE; - } - else if (0 == strcmp(method, "LABEL")) { - *sc = SC_M_LABEL; - } - else if (0 == strcmp(method, "MERGE")) { - *sc = SC_M_MERGE; - } - else if (0 == strcmp(method, "BASELINE-CONTROL")) { - *sc = SC_M_BASELINE_CONTROL; - } - else if (0 == strcmp(method, "MKACTIVITY")) { - *sc = SC_M_MKACTIVITY; - } - else { - rc = JK_FALSE; - } + /* Note: the following code was generated by the "shilka" tool from + the "cocom" parsing/compilation toolkit. It is an optimized lookup + based on analysis of the input keywords. Postprocessing was done + on the shilka output, but the basic structure and analysis is + from there. Should new HTTP methods be added, then manual insertion + into this code is fine, or simply re-running the shilka tool on + the appropriate input. */ + + /* Note: it is also quite reasonable to just use our method_registry, + but I'm assuming (probably incorrectly) we want more speed here + (based on the optimizations the previous code was doing). */ + + switch (len) + { + case 3: + switch (method[0]) + { + case 'P': + return (method[1] == 'U' + && method[2] == 'T' + ? SC_M_PUT : UNKNOWN_METHOD); + case 'G': + return (method[1] == 'E' + && method[2] == 'T' + ? SC_M_GET : UNKNOWN_METHOD); + default: + return UNKNOWN_METHOD; + } - return rc; -} + case 4: + switch (method[0]) + { + case 'H': + return (method[1] == 'E' + && method[2] == 'A' + && method[3] == 'D' + ? SC_M_GET : UNKNOWN_METHOD); + case 'P': + return (method[1] == 'O' + && method[2] == 'S' + && method[3] == 'T' + ? SC_M_POST : UNKNOWN_METHOD); + case 'M': + return (method[1] == 'O' + && method[2] == 'V' + && method[3] == 'E' + ? SC_M_MOVE : UNKNOWN_METHOD); + case 'L': + return (method[1] == 'O' + && method[2] == 'C' + && method[3] == 'K' + ? SC_M_LOCK : UNKNOWN_METHOD); + case 'C': + return (method[1] == 'O' + && method[2] == 'P' + && method[3] == 'Y' + ? SC_M_COPY : UNKNOWN_METHOD); + default: + return UNKNOWN_METHOD; + } -#define UNKNOWN_METHOD (-1) + case 5: + switch (method[2]) + { + case 'R': + return (memcmp(method, "MERGE", 5) == 0 + ? SC_M_MERGE : UNKNOWN_METHOD); + case 'C': + return (memcmp(method, "MKCOL", 5) == 0 + ? SC_M_MKCOL : UNKNOWN_METHOD); + case 'B': + return (memcmp(method, "LABEL", 5) == 0 + ? SC_M_LABEL : UNKNOWN_METHOD); + case 'A': + return (memcmp(method, "TRACE", 5) == 0 + ? SC_M_TRACE : UNKNOWN_METHOD); + default: + return UNKNOWN_METHOD; + } + + case 6: + switch (method[0]) + { + case 'U': + switch (method[5]) + { + case 'K': + return (memcmp(method, "UNLOCK", 6) == 0 + ? SC_M_UNLOCK : UNKNOWN_METHOD); + case 'E': + return (memcmp(method, "UPDATE", 6) == 0 + ? SC_M_UPDATE : UNKNOWN_METHOD); + default: + return UNKNOWN_METHOD; + } + case 'R': + return (memcmp(method, "REPORT", 6) == 0 + ? SC_M_REPORT : UNKNOWN_METHOD); + case 'D': + return (memcmp(method, "DELETE", 6) == 0 + ? SC_M_DELETE : UNKNOWN_METHOD); + default: + return UNKNOWN_METHOD; + } + + case 7: + switch (method[1]) + { + case 'P': + return (memcmp(method, "OPTIONS", 7) == 0 + ? SC_M_OPTIONS : UNKNOWN_METHOD); + case 'H': + return (memcmp(method, "CHECKIN", 7) == 0 + ? SC_M_CHECKIN : UNKNOWN_METHOD); + default: + return UNKNOWN_METHOD; + } + + case 8: + switch (method[0]) + { + case 'P': + return (memcmp(method, "PROPFIND", 8) == 0 + ? SC_M_PROPFIND : UNKNOWN_METHOD); + case 'C': + return (memcmp(method, "CHECKOUT", 8) == 0 + ? SC_M_CHECKOUT : UNKNOWN_METHOD); + default: + return UNKNOWN_METHOD; + } + + case 9: + return (memcmp(method, "PROPPATCH", 9) == 0 + ? SC_M_PROPPATCH : UNKNOWN_METHOD); + + case 10: + switch (method[0]) + { + case 'U': + return (memcmp(method, "UNCHECKOUT", 10) == 0 + ? SC_M_UNCHECKOUT : UNKNOWN_METHOD); + case 'M': + return (memcmp(method, "MKACTIVITY", 10) == 0 + ? SC_M_MKACTIVITY : UNKNOWN_METHOD); + default: + return UNKNOWN_METHOD; + } + + case 11: + return (memcmp(method, "MKWORKSPACE", 11) == 0 + ? SC_M_MKWORKSPACE : UNKNOWN_METHOD); + + case 15: + return (memcmp(method, "VERSION-CONTROL", 15) == 0 + ? SC_M_VERSION_CONTROL : UNKNOWN_METHOD); + + case 16: + return (memcmp(method, "BASELINE-CONTROL", 16) == 0 + ? SC_M_BASELINE_CONTROL : UNKNOWN_METHOD); + + default: + return UNKNOWN_METHOD; + } + + /* NOTREACHED */ +} static int sc_for_req_header(const char *header_name) { @@ -296,12 +373,13 @@ jk_ws_service_t *s, jk_logger_t *l, ajp_endpoint_t * ae) { - unsigned char method; - unsigned i; + int method; + unsigned int i; JK_TRACE_ENTER(l); - if (!sc_for_req_method(s->method, &method)) { + if ((method = sc_for_req_method(s->method, + strlen(s->method))) == UNKNOWN_METHOD) { jk_log(l, JK_LOG_ERROR, "No such method %s\n", s->method); @@ -310,7 +388,7 @@ } if (jk_b_append_byte(msg, JK_AJP13_FORWARD_REQUEST) || - jk_b_append_byte(msg, method) || + jk_b_append_byte(msg, (unsigned char)method) || jk_b_append_string(msg, s->protocol) || jk_b_append_string(msg, s->req_uri) || jk_b_append_string(msg, s->remote_addr) ||
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]