httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Joe Orton <...@light.plus.com>
Subject [PATCH] Invalid request range handling
Date Mon, 09 Oct 2000 21:50:43 GMT
RFC2616 section 14.35.1 says that if a range header is received with an
invalid range spec., the whole header MUST be ignored. Currently 1.3.12
does this correctly for range headers with a single range spec, but
doesn't do this when the header has *multiple* range specs... e.g.:
(note that 5-1 is invalid)

GET /foo HTTP/1.1
Host: www
Range: bytes=1-1,5-1

HTTP/1.1 206 Partial Content
Date: Mon, 09 Oct 2000 21:12:15 GMT
Server: Apache/1.3.12 (Unix) DAV/1.0.2-dev
Last-Modified: Mon, 09 Oct 2000 21:02:22 GMT
ETag: "bf74-b-39e2325e"
Accept-Ranges: bytes
Content-Length: 96
Content-Type: multipart/byteranges; boundary=39e234af390e


--39e234af390e
Content-type: text/plain
Content-range: bytes 1-1/11

2
--39e234af390e--


Here's a patch which fixes this:

--- http_protocol.c.orig	Mon Oct  9 21:41:22 2000
+++ http_protocol.c	Mon Oct  9 22:46:32 2000
@@ -235,13 +235,21 @@
         /* a multiple range */
         const char *r_range = ap_pstrdup(r->pool, range + 6);
         long tlength = 0;
-
-        r->byterange = 2;
+	int ret;
+	
         r->boundary = ap_psprintf(r->pool, "%lx%lx",
 				r->request_time, (long) getpid());
-        while (internal_byterange(0, &tlength, r, &r_range, NULL, NULL));
+        do {
+	    /* Loop while we have another range spec to process */
+	    ret = internal_byterange(0, &tlength, r, &r_range, NULL, NULL);
+	} while (ret == 1);
+	/* If an error occured processing one of the range specs, we
+	 * must fail */
+	if (ret < 0)
+	    return 0;
         ap_table_setn(r->headers_out, "Content-Length",
 	    ap_psprintf(r->pool, "%ld", tlength));
+        r->byterange = 2;
     }
 
     r->status = PARTIAL_CONTENT;
@@ -262,8 +270,8 @@
  * If it is called with realreq=0, it will add to tlength the length
  * it *would* have used with realreq=1.
  *
- * Either case will return 1 if it should be called again, and 0
- * when done.
+ * Either case will return 1 if it should be called again, 0 when done,
+ * or -1 if an error occurs AND realreq=0.
  */
 static int internal_byterange(int realreq, long *tlength, request_rec *r,
                               const char **r_range, long *offset, long *length)
@@ -296,9 +304,12 @@
 #ifdef CHARSET_EBCDIC
         POP_EBCDIC_OUTPUTCONVERSION_STATE(r->connection->client);
 #endif /*CHARSET_EBCDIC*/
-        /* Skip this one */
-        return internal_byterange(realreq, tlength, r, r_range, offset,
-                                  length);
+	if (!realreq)
+	    /* Return error on invalid syntax */
+	    return -1;
+	else
+	    /* Should never get here */
+	    return 0;
     }
 
     if (r->byterange > 1) {

Mime
View raw message