dgaudet 98/03/13 18:43:48
Modified: src CHANGES
src/main http_main.c util.c
Log:
Another 1.5% -- this is the basics of the istable patch I posted a few
times, but without the compile-time generated table. I still plan to
do the compile-time generated table. I decided not to do it in ap_ since
the table was really tied into functions in util.c.
find_token() completely rewritten so that it doesn't chew up memory. Take
out some dead code as well.
Revision Changes Path
1.708 +2 -0 apache-1.3/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
retrieving revision 1.707
retrieving revision 1.708
diff -u -r1.707 -r1.708
--- CHANGES 1998/03/14 00:33:44 1.707
+++ CHANGES 1998/03/14 02:43:42 1.708
@@ -1,5 +1,7 @@
Changes with Apache 1.3b6
+ *) util.c cleanup and speedup. [Dean Gaudet]
+
*) API: Clarification, pstrndup() will always copy n bytes of the source
and NUL terminate at the (n+1)st byte. [Dean Gaudet]
1.303 +4 -0 apache-1.3/src/main/http_main.c
Index: http_main.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/main/http_main.c,v
retrieving revision 1.302
retrieving revision 1.303
diff -u -r1.302 -r1.303
--- http_main.c 1998/03/13 23:44:44 1.302
+++ http_main.c 1998/03/14 02:43:45 1.303
@@ -2957,6 +2957,9 @@
}
+/* DEAN WILL CLEAN THIS UP! */
+extern void util_init(void);
+
/* Some init code that's common between win32 and unix... well actually
* some of it is #ifdef'd but was duplicated before anyhow. This stuff
* is still a mess.
@@ -2986,6 +2989,7 @@
pconf = permanent_pool;
ptrans = make_sub_pool(pconf);
+ util_init();
util_uri_init();
pcommands = make_sub_pool(NULL);
1.100 +77 -57 apache-1.3/src/main/util.c
Index: util.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/main/util.c,v
retrieving revision 1.99
retrieving revision 1.100
diff -u -r1.99 -r1.100
--- util.c 1998/03/14 00:50:38 1.99
+++ util.c 1998/03/14 02:43:46 1.100
@@ -74,6 +74,54 @@
extern int fclose(FILE *);
#endif
+/* A bunch of functions in util.c scan strings looking for certain
characters.
+ * To make that more efficient we encode a lookup table.
+ */
+#define T_ESCAPE_SHELL_CMD (0x01)
+#define T_ESCAPE_PATH_SEGMENT (0x02)
+#define T_OS_ESCAPE_PATH (0x04)
+#define T_HTTP_TOKEN_STOP (0x08)
+
+static unsigned char test_char_table[256];
+
+#define TEST_CHAR(c, f) (test_char_table[((unsigned char)(c)) & 0xff] &
(f))
+
+/* XXX: this should be compile-time initialized so that test_char_table can
+ * live in read-only memory and not require backing store across fork().
+ */
+void util_init(void)
+{
+ unsigned c;
+ unsigned char flags;
+
+ /* explicitly deal with NUL in case some strchr() do bogosity with it */
+ test_char_table[0] = 0;
+
+ for (c = 1; c < 256; ++c) {
+ flags = 0;
+
+ /* escape_shell_cmd */
+ if (strchr("&;`'\"|*?~<>^()[]{}$\\\n", c)) {
+ flags |= T_ESCAPE_SHELL_CMD;
+ }
+
+ if (!isalnum(c) && !strchr("$-_.+!*'(),:@&=~", c)) {
+ flags |= T_ESCAPE_PATH_SEGMENT;
+ }
+
+ if (!isalnum(c) && !strchr("$-_.+!*'(),:@&=/~", c)) {
+ flags |= T_OS_ESCAPE_PATH;
+ }
+
+ /* these are the "tspecials" from RFC2068 */
+ if (iscntrl(c) || strchr(" \t()<>@,;:\\/[]?={}", c)) {
+ flags |= T_HTTP_TOKEN_STOP;
+ }
+
+ test_char_table[c] = flags;
+ }
+}
+
API_VAR_EXPORT const char month_snames[12][4] =
{
@@ -944,60 +992,42 @@
return token;
}
-static char *tspecials = " \t()<>@,;:\\/[]?={}";
-
-/* Next HTTP token from a header line. Warning --- destructive!
- * Use only with a copy!
- */
-
-static char *next_token(char **toks)
-{
- char *cp = *toks;
- char *ret;
-
- while (*cp && (iscntrl(*cp) || strchr(tspecials, *cp))) {
- if (*cp == '"')
- while (*cp && (*cp != '"'))
- ++cp;
- else
- ++cp;
- }
-
- if (!*cp)
- ret = NULL;
- else {
- ret = cp;
-
- while (*cp && !iscntrl(*cp) && !strchr(tspecials, *cp))
- ++cp;
-
- if (*cp) {
- *toks = cp + 1;
- *cp = '\0';
- }
- else
- *toks = cp;
- }
-
- return ret;
-}
+/* find http tokens, see the definition of token from RFC2068 */
API_EXPORT(int) find_token(pool *p, const char *line, const char *tok)
{
- char *ltok;
- char *lcopy;
+ const char *start_token;
+ const char *s;
if (!line)
return 0;
- lcopy = pstrdup(p, line);
- while ((ltok = next_token(&lcopy)))
- if (!strcasecmp(ltok, tok))
+ s = line;
+ for (;;) {
+ /* find start of token, skip all stop characters, note NUL
+ * isn't a token stop, so we don't need to test for it
+ */
+ while (TEST_CHAR(*s, T_HTTP_TOKEN_STOP)) {
+ ++s;
+ }
+ if (!*s) {
+ return 0;
+ }
+ start_token = s;
+ /* find end of the token */
+ while (*s && !TEST_CHAR(*s, T_HTTP_TOKEN_STOP)) {
+ ++s;
+ }
+ if (!strncasecmp(start_token, tok, s - start_token)) {
return 1;
-
- return 0;
+ }
+ if (!*s) {
+ return 0;
+ }
+ }
}
+
API_EXPORT(int) find_last_token(pool *p, const char *line, const char *tok)
{
int llen, tlen, lidx;
@@ -1035,7 +1065,7 @@
}
#endif
- if (strchr("&;`'\"|*?~<>^()[]{}$\\\n", cmd[x])) {
+ if (TEST_CHAR(cmd[x], T_ESCAPE_SHELL_CMD)) {
for (y = l + 1; y > x; y--)
cmd[y] = cmd[y - 1];
l++; /* length has been increased */
@@ -1164,12 +1194,7 @@
for (x = 0, y = 0; segment[x]; x++, y++) {
char c = segment[x];
-#ifndef CHARSET_EBCDIC
- if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') && (c < '0' || c > '9')
-#else /* CHARSET_EBCDIC*/
- if (!isalnum(c)
-#endif /*CHARSET_EBCDIC*/
- && !strchr("$-_.+!*'(),:@&=~", c)) {
+ if (TEST_CHAR(c, T_ESCAPE_PATH_SEGMENT)) {
c2x(c, ©[y]);
y += 2;
}
@@ -1196,12 +1221,7 @@
}
for (; *path; ++path) {
char c = *path;
-#ifndef CHARSET_EBCDIC
- if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') && (c < '0' || c > '9')
-#else /* CHARSET_EBCDIC*/
- if (!isalnum(c)
-#endif /*CHARSET_EBCDIC*/
- && !strchr("$-_.+!*'(),:@&=/~", c)) {
+ if (TEST_CHAR(c, T_OS_ESCAPE_PATH)) {
c2x(c, s);
s += 3;
}