]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
The 416 "range not satisfiable" response would include a
authorMartin Kraemer <martin@apache.org>
Tue, 8 Jan 2002 15:09:48 +0000 (15:09 +0000)
committerMartin Kraemer <martin@apache.org>
Tue, 8 Jan 2002 15:09:48 +0000 (15:09 +0000)
Content-Length header set to the size of the resource, but no body was
actually returned (r->header_only was set to 1). This appeared as a
premature EOF to the client.
Submitted by: Joe Orton <joe@manyfish.co.uk>
Reviewed by: Martin Kraemer

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x@92767 13f79535-47bb-0310-9956-ffa450edef68

src/CHANGES
src/main/http_protocol.c

index 3556cf12e919dfbe31ca87fbbd5764476e66d475..0591c04482ff8eb5bc74321265379aeaf2562fb1 100644 (file)
@@ -1,5 +1,8 @@
 Changes with Apache 1.3.23
 
+  *) Fix incorrect "Content-Length" header in the 416 "range not
+     satisfiable" response. [Joe Orton <joe@manyfish.co.uk>]
+
   *) Add FileETag directive to control fields used when constructing
      an ETag for a file-based resource.  Historically the inode,
      size, and mtimehave been used, but the inode factor broke
index a9cee504a3b308a1f7549882a80cb23a861de4cb..dc21559273de00b857b717cf0ecf2de6118f9ca0 100644 (file)
@@ -361,6 +361,7 @@ API_EXPORT(int) ap_set_byterange(request_rec *r)
        else {
            ap_table_setn(r->headers_out, "Content-Range",
                ap_psprintf(r->pool, "bytes */%ld", r->clength));
+           ap_set_content_length(r, 0);                          
            r->boundary = NULL;
            r->range = range;
            r->header_only = 1;
@@ -1040,16 +1041,43 @@ static int read_request_line(request_rec *r)
         r->protocol  = ap_pstrdup(r->pool, "HTTP/1.0");
         return 0;
     }
-
     r->assbackwards = (ll[0] == '\0');
     r->protocol = ap_pstrdup(r->pool, ll[0] ? ll : "HTTP/0.9");
 
-    if (2 == sscanf(r->protocol, "HTTP/%u.%u", &major, &minor)
-      && minor < HTTP_VERSION(1,0))    /* don't allow HTTP/0.1000 */
-       r->proto_num = HTTP_VERSION(major, minor);
-    else
-       r->proto_num = HTTP_VERSION(1,0);
+    /* The following test tries to skip past the "HTTP/nn.mm"
+     * protocol string, collecting major=nn and minor=mm.
+     * ll is advanced past "HTTP/nn.mm" so that it can be checked
+     * for proper string termination (only valid chars: \r\n).
+     */
+    if (memcmp(ll,"HTTP/",5) == 0 && isdigit(ll[5])) {
 
+        /* Read major protocol level: */
+        major = strtol(&ll[5], &ll, 10);
+        if (errno != ERANGE && ll[0] == '/' && isdigit(ll[1])) {
+
+            /* Read minor protocol level: */
+            minor = strtol(&ll[1], &ll, 10);
+
+           if (errno != ERANGE) { 
+                if (minor < HTTP_VERSION(1,0)) /* don't allow HTTP/0.1000 */
+                    r->proto_num = HTTP_VERSION(major, minor);
+                else
+                    r->proto_num = HTTP_VERSION(1,0);
+           }
+       }
+    }
+    /* If the request does not end after the "HTTP/x.y\r\n" (or after the
+     * URI in HTTP/0.9), then signal an error condition [400 Bad Request].
+     */
+    if (ll[strspn(ll," \r\n")] != '\0') {
+        ap_table_setn(r->notes, "error-notes",
+                      "Request line not ending properly after \"HTTP/x.y\":"
+                      "<PRE>\n", ap_escape_html(r->pool, r->protocol), "</PRE>");
+        r->status    = HTTP_BAD_REQUEST;
+        r->proto_num = HTTP_VERSION(1,0);
+        r->protocol  = ap_pstrdup(r->pool, "HTTP/1.0");
+        return 0;
+    }
     return 1;
 }