Commit 831beca6 authored by Ryan Bloom's avatar Ryan Bloom
Browse files

Make the server return HTTP_RANGE_NOT_SATISFIABLE if the all of the

requested ranges begin after the end of the response.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@87390 13f79535-47bb-0310-9956-ffa450edef68
parent 6599d10b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
Changes with Apache 2.0b1
  *) Return HTTP_RANGE_NOT_SATISFIABLE if the every range requested starts
     after the end of the response. [Ryan Bloom]

  *) Get byterange requests working with responses that do not have a
     content-length.  Because of the way byterange requests work, we have to
     have all of the data before we can actually do the byterange, so we
+31 −6
Original line number Diff line number Diff line
@@ -181,7 +181,7 @@ static int parse_byterange(char *range, apr_off_t clength,
        *end = clength - 1;

    if (*start > *end)
	return 0;
	return -1;

    return (*start > 0 || *end < clength - 1);
}
@@ -224,10 +224,16 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(
    char *current;
    const char *bound_head;
    int clength = 0;
    apr_status_t rv;
    int found = 0;

    if (!ctx) {
        int num_ranges = ap_set_byterange(r);
 
        if (num_ranges == -1) {
            ap_remove_output_filter(f);
            return HTTP_RANGE_NOT_SATISFIABLE;
        }
        if (num_ranges == 0) {
            ap_remove_output_filter(f);
            return ap_pass_brigade(f->next, bb);
@@ -287,7 +293,7 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(
    bsend = ap_brigade_create(r->pool);

    while ((current = ap_getword(r->pool, &r->range, ',')) &&
           parse_byterange(current, clength, &range_start, &range_end)) {
           (rv = parse_byterange(current, clength, &range_start, &range_end))) {
        const char *str;
        apr_size_t n;
        const char *range;
@@ -297,6 +303,13 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(
        apr_size_t segment_length;
        apr_off_t curr_offset = 0;

        if (rv == -1) {
            continue;
        }        
        else {
            found = 1;
        }

        /* ### this is so bogus, but not dealing with it right now */
        range = loc = apr_pcalloc(r->pool, range_length + 1);

@@ -373,6 +386,12 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(
        AP_BRIGADE_INSERT_TAIL(bsend, e);
    }

    if (found == 0) {
        ap_remove_output_filter(f);
        r->status = HTTP_OK;
        return HTTP_RANGE_NOT_SATISFIABLE;
    }

    if (ctx->num_ranges > 1) {
        const char *end;

@@ -2398,12 +2417,13 @@ static int ap_set_byterange(request_rec *r)
    ct = make_content_type(r, r->content_type);

    if (!ap_strchr_c(range, ',')) {
        int rv;
        /* A single range */

        /* parse_byterange() modifies the contents, so make a copy */
        if (!parse_byterange(apr_pstrdup(r->pool, range + 6), r->clength,
                             &range_start, &range_end)) {
            return 0;
        /* rvarse_byterange() modifies the contents, so make a copy */
        if ((rv = parse_byterange(apr_pstrdup(r->pool, range + 6), r->clength,
                             &range_start, &range_end)) <= 0) {
            return rv;
        }
        apr_table_setn(r->headers_out, "Content-Range",
                       apr_psprintf(r->pool, "bytes " BYTERANGE_FMT,
@@ -3340,6 +3360,11 @@ AP_DECLARE(void) ap_send_error_response(request_rec *r, int recursive_error)
    char *custom_response;
    const char *location = apr_table_get(r->headers_out, "Location");

    /* At this point, we are starting the response over, so we have to reset
     * this value.
     */
    r->eos_sent = 0;

    /*
     * It's possible that the Location field might be in r->err_headers_out
     * instead of r->headers_out; use the latter if possible, else the