coar 99/01/27 04:16:04
Modified: src CHANGES src/include ap_mmn.h httpd.h src/main gen_test_char.c http_protocol.c util.c Log: ETags aren't normal tokens by the RFC 2068 definition; they explicitly contain quoted strings and can include stuff *outside* the quotes as well ('W/' for a weak ETag). So add a new function that treats *everything* except ',' and ' ' (and not even those, if they're in a quoted string) as part of the token, and fix the ETag checks to use it. PR: 2065, 3657 Revision Changes Path 1.1224 +3 -0 apache-1.3/src/CHANGES Index: CHANGES =================================================================== RCS file: /home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.1223 retrieving revision 1.1224 diff -u -r1.1223 -r1.1224 --- CHANGES 1999/01/25 22:55:33 1.1223 +++ CHANGES 1999/01/27 12:15:58 1.1224 @@ -1,5 +1,8 @@ Changes with Apache 1.3.5 + *) Fix checking of ETags and other opaque 'tokens' by adding + ap_find_opaque_token(). PR#2065, 3657 [Ken Coar] + *) Add ability to handle DES or MD5 authentication passwords. [Ryan Bloom <[EMAIL PROTECTED]>] 1.23 +3 -1 apache-1.3/src/include/ap_mmn.h Index: ap_mmn.h =================================================================== RCS file: /home/cvs/apache-1.3/src/include/ap_mmn.h,v retrieving revision 1.22 retrieving revision 1.23 diff -u -r1.22 -r1.23 --- ap_mmn.h 1999/01/09 00:21:33 1.22 +++ ap_mmn.h 1999/01/27 12:16:00 1.23 @@ -203,6 +203,8 @@ * scan_script_header -> ap_scan_script_header_err * - reordered entries in request_rec that were waiting * for a non-binary-compatible release. + * 19990108-1 - add ap_find_opaque_token() for things like ETags + * (1.3.5-dev) which can contain opaque quoted strings */ #define MODULE_MAGIC_COOKIE 0x41503133UL /* "AP13" */ @@ -210,7 +212,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 19990108 #endif -#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 1 /* 0...n */ #define MODULE_MAGIC_NUMBER MODULE_MAGIC_NUMBER_MAJOR /* backward compat */ /* Useful for testing for features. */ 1.265 +2 -0 apache-1.3/src/include/httpd.h Index: httpd.h =================================================================== RCS file: /home/cvs/apache-1.3/src/include/httpd.h,v retrieving revision 1.264 retrieving revision 1.265 diff -u -r1.264 -r1.265 --- httpd.h 1999/01/10 07:48:59 1.264 +++ httpd.h 1999/01/27 12:16:00 1.265 @@ -936,6 +936,8 @@ API_EXPORT(char *) ap_get_token(pool *p, const char **accept_line, int accept_white); API_EXPORT(int) ap_find_token(pool *p, const char *line, const char *tok); +API_EXPORT(int) ap_find_opaque_token(pool *p, const char *line, + const char *tok); API_EXPORT(int) ap_find_last_token(pool *p, const char *line, const char *tok); API_EXPORT(int) ap_is_url(const char *u); 1.5 +9 -1 apache-1.3/src/main/gen_test_char.c Index: gen_test_char.c =================================================================== RCS file: /home/cvs/apache-1.3/src/main/gen_test_char.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gen_test_char.c 1998/07/08 17:47:05 1.4 +++ gen_test_char.c 1999/01/27 12:16:01 1.5 @@ -8,6 +8,7 @@ #define T_ESCAPE_PATH_SEGMENT (0x02) #define T_OS_ESCAPE_PATH (0x04) #define T_HTTP_TOKEN_STOP (0x08) +#define T_HTTP_OPAQUETOKEN_STOP (0x10) int main(int argc, char *argv[]) { @@ -20,13 +21,15 @@ "#define T_ESCAPE_PATH_SEGMENT (%u)\n" "#define T_OS_ESCAPE_PATH (%u)\n" "#define T_HTTP_TOKEN_STOP (%u)\n" +"#define T_HTTP_OPAQUETOKEN_STOP (%u)\n" "\n" "static const unsigned char test_char_table[256] = {\n" " 0,", T_ESCAPE_SHELL_CMD, T_ESCAPE_PATH_SEGMENT, T_OS_ESCAPE_PATH, - T_HTTP_TOKEN_STOP); + T_HTTP_TOKEN_STOP, + T_HTTP_OPAQUETOKEN_STOP); /* we explicitly dealt with NUL above * in case some strchr() do bogosity with it */ @@ -52,6 +55,11 @@ /* these are the "tspecials" from RFC2068 */ if (ap_iscntrl(c) || strchr(" \t()<>@,;:\\/[]?={}", c)) { flags |= T_HTTP_TOKEN_STOP; + } + + /* some tokens (like etags) are opaque strings; stop at the end */ + if (ap_iscntrl(c) || strchr(" ,", c)) { + flags |= T_HTTP_OPAQUETOKEN_STOP; } printf("%u%c", flags, (c < 255) ? ',' : ' '); 1.254 +4 -2 apache-1.3/src/main/http_protocol.c Index: http_protocol.c =================================================================== RCS file: /home/cvs/apache-1.3/src/main/http_protocol.c,v retrieving revision 1.253 retrieving revision 1.254 diff -u -r1.253 -r1.254 --- http_protocol.c 1999/01/08 17:54:41 1.253 +++ http_protocol.c 1999/01/27 12:16:01 1.254 @@ -404,7 +404,8 @@ */ if ((if_match = ap_table_get(r->headers_in, "If-Match")) != NULL) { if ((etag == NULL) || - ((if_match[0] != '*') && !ap_find_token(r->pool, if_match, etag))) { + ((if_match[0] != '*') + && !ap_find_opaque_token(r->pool, if_match, etag))) { return HTTP_PRECONDITION_FAILED; } } @@ -437,7 +438,8 @@ int rstatus; if ((if_nonematch[0] == '*') - || ((etag != NULL) && ap_find_token(r->pool, if_nonematch, etag))) { + || ((etag != NULL) + && ap_find_opaque_token(r->pool, if_nonematch, etag))) { rstatus = (r->method_number == M_GET) ? HTTP_NOT_MODIFIED : HTTP_PRECONDITION_FAILED; return rstatus; 1.147 +61 -0 apache-1.3/src/main/util.c Index: util.c =================================================================== RCS file: /home/cvs/apache-1.3/src/main/util.c,v retrieving revision 1.146 retrieving revision 1.147 diff -u -r1.146 -r1.147 --- util.c 1999/01/21 19:17:09 1.146 +++ util.c 1999/01/27 12:16:02 1.147 @@ -1057,6 +1057,67 @@ } } +/* + * Find opaque HTTP tokens, which have no internal semantics and end + * at the first unquoted ',' or ' '. + */ +API_EXPORT(int) ap_find_opaque_token(pool *p, const char *line, + const char *tok) +{ + const unsigned char *start_token; + const unsigned char *s; + char stop_quote = '\0'; + + if (!line) { + return 0; + } + + s = (const unsigned char *)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_OPAQUETOKEN_STOP)) { + ++s; + } + if (!*s) { + return 0; + } + start_token = s; + /* + * Find end of the token + */ + while (*s) { + /* + * If we see the beginning of a quoted string ("foo" or <foo>), + * mark the end character so we know when to stop skipping. + */ + if (!stop_quote && ((*s == '"') || (*s == '<'))) { + stop_quote = (*s == '"') ? '"' : '>'; + } + else if (*s == stop_quote) { + stop_quote = '\0'; + } + /* + * If we're not inside a quoted string, check to see if we're + * at the end of the token. + */ + else if (!stop_quote && TEST_CHAR(*s, T_HTTP_OPAQUETOKEN_STOP)) { + break; + } + ++s; + } + if (!strncmp((const char *)start_token, (const char *)tok, + s - start_token)) { + return 1; + } + if (!*s) { + return 0; + } + } +} + API_EXPORT(int) ap_find_last_token(pool *p, const char *line, const char *tok) {