You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by Alexei Kosut <ak...@hyperreal.com> on 1997/02/11 07:33:37 UTC

cvs commit: apache/src http_protocol.c

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