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)
{