Received: by taz.hyperreal.com (8.8.4/V2.0) id WAA19003; Mon, 10 Feb 1997 22:33:41 -0800 (PST) Received: by taz.hyperreal.com (8.8.4/V2.0) id WAA18990; Mon, 10 Feb 1997 22:33:37 -0800 (PST) Date: Mon, 10 Feb 1997 22:33:37 -0800 (PST) From: Alexei Kosut Message-Id: <199702110633.WAA18990@taz.hyperreal.com> To: apache-cvs@hyperreal.com Subject: cvs commit: apache/src http_protocol.c Sender: apache-cvs-owner@apache.org Precedence: bulk Reply-To: new-httpd@hyperreal.com akosut 97/02/10 22:33:36 Modified: src http_protocol.c Log: Add Content-Length header to multipart/byteranges responses. Reviewed by: Roy T. Fielding, Dean Guadet Revision Changes Path 1.99 +49 -11 apache/src/http_protocol.c Index: http_protocol.c =================================================================== RCS file: /export/home/cvs/apache/src/http_protocol.c,v retrieving revision 1.98 retrieving revision 1.99 diff -C3 -r1.98 -r1.99 *** http_protocol.c 1997/02/06 21:40:35 1.98 --- http_protocol.c 1997/02/11 06:33:34 1.99 *************** *** 106,111 **** --- 106,113 ---- return 1; } + static int internal_byterange(int, long*, request_rec*, char**, long*, long*); + int set_byterange (request_rec *r) { char *range = table_get (r->headers_in, "Range"); *************** *** 161,171 **** else { /* a multiple range */ char boundary[33]; /* Long enough */ r->byterange = 2; - table_unset(r->headers_out, "Content-Length"); ap_snprintf(boundary, sizeof(boundary), "%lx%lx", r->request_time, (long)getpid()); r->boundary = pstrdup(r->pool, boundary); } r->status = PARTIAL_CONTENT; --- 163,177 ---- else { /* a multiple range */ char boundary[33]; /* Long enough */ + char *r_range = pstrdup(r->pool, range + 6); + long tlength = 0; r->byterange = 2; ap_snprintf(boundary, sizeof(boundary), "%lx%lx", r->request_time, (long)getpid()); r->boundary = pstrdup(r->pool, boundary); + while (internal_byterange(0, &tlength, r, &r_range, NULL, NULL)); + ap_snprintf(ts, sizeof(ts), "%ld", tlength); + table_set(r->headers_out, "Content-Length", ts); } r->status = PARTIAL_CONTENT; *************** *** 175,205 **** } int each_byterange (request_rec *r, long *offset, long *length) { long range_start, range_end; char *range; ! if (!*r->range) { ! if (r->byterange > 1) ! rvputs(r, "\015\012--", r->boundary, "--\015\012", NULL); return 0; } ! range = getword_nc(r->pool, &r->range, ','); if (!parse_byterange(range, r->clength, &range_start, &range_end)) ! return each_byterange(r, offset, length); /* Skip this one */ if (r->byterange > 1) { char *ct = r->content_type ? r->content_type : default_type(r); char ts[MAX_STRING_LEN]; ! ap_snprintf(ts, sizeof(ts), "%ld-%ld/%ld", range_start, range_end, r->clength); ! rvputs(r, "\015\012--", r->boundary, "\015\012Content-type: ", ct, "\015\012Content-range: bytes ", ts, "\015\012\015\012", NULL); } ! *offset = range_start; ! *length = range_end - range_start + 1; return 1; } --- 181,243 ---- } int each_byterange (request_rec *r, long *offset, long *length) { + return internal_byterange(1, NULL, r, &r->range, offset, length); + } + + /* If this function is called with realreq=1, it will spit out + * the correct headers for a byterange chunk, and set offset and + * length to the positions they should be. + * + * 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. + * + */ + + static int internal_byterange(int realreq, long *tlength, request_rec *r, + char **r_range, long *offset, long *length) { long range_start, range_end; char *range; ! if (!**r_range) { ! if (r->byterange > 1) { ! if (realreq) ! rvputs(r, "\015\012--", r->boundary, "--\015\012", NULL); ! else ! *tlength += 4 + strlen(r->boundary) + 4; ! } return 0; } ! range = getword_nc(r->pool, r_range, ','); if (!parse_byterange(range, r->clength, &range_start, &range_end)) ! /* Skip this one */ ! return internal_byterange(realreq, tlength, r, r_range, offset, ! length); if (r->byterange > 1) { char *ct = r->content_type ? r->content_type : default_type(r); char ts[MAX_STRING_LEN]; ! ap_snprintf(ts, sizeof(ts), "%ld-%ld/%ld", range_start, range_end, r->clength); ! if (realreq) ! rvputs(r, "\015\012--", r->boundary, "\015\012Content-type: ", ct, "\015\012Content-range: bytes ", ts, "\015\012\015\012", NULL); + else + *tlength += 4 + strlen(r->boundary) + 16 + strlen(ct) + 23 + + strlen(ts) + 4; } ! if (realreq) { ! *offset = range_start; ! *length = range_end - range_start + 1; ! } ! else { ! *tlength += range_end - range_start + 1; ! } return 1; } *************** *** 228,234 **** (r->server->keep_alive_max > r->connection->keepalives)) && (r->server->keep_alive_timeout > 0) && (r->status == USE_LOCAL_COPY || r->header_only || length || tenc || ! ((r->proto_num >= 1001) && (r->byterange > 1 || (r->chunked = 1)))) && (!find_token(r->pool, conn, "close")) && ((ka_sent = find_token(r->pool, conn, "keep-alive")) || r->proto_num >= 1001)) { --- 266,272 ---- (r->server->keep_alive_max > r->connection->keepalives)) && (r->server->keep_alive_timeout > 0) && (r->status == USE_LOCAL_COPY || r->header_only || length || tenc || ! ((r->proto_num >= 1001) && (r->chunked = 1))) && (!find_token(r->pool, conn, "close")) && ((ka_sent = find_token(r->pool, conn, "keep-alive")) || r->proto_num >= 1001)) {