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]