Article delegate-en/3094 of [1-5169] on the server localhost:119
  upper oldest olders older1 this newer1 newers latest
search
[Top/Up] [oldest] - [Older+chunk] - [Newer+chunk] - [newest + Check]
[Reference:<_A3093@delegate-en.ML_>]
Newsgroups: mail-lists.delegate-en

[DeleGate-En] Re: http partial download in origin mode
27 Dec 2005 06:51:00 GMT feedback@delegate.org (Yutaka Sato)
The DeleGate Project


Hi,

In message <_A3093@delegate-en.ML_> on 12/27/05(03:26:21)
you Martin Papadopoulos <payeabdyi-kvnd4bcus3jr.ml@ml.delegate.org> wrote:
 |when delegate is in origin http mode the partial content retrievement
 |does not function. =-O
 |is there a workaround / bugfix available ?

In your LOGFILE, you will find what kind of Range: header field was sent
in the request message, like this for example:

  12/27 15:40:04.78 [26815] 1+1: #HT11 (10) Range: bytes=20-29^M

There are several format of Range header in a HTTP/1.1 request, as follows:

  (1) Range: bytes=x-y
  (2) Range: bytes=x-
  (3) Range: bytes=-y
  (4) Range: bytes=x-y,a-b,...

Only the format (1) has been available since DeleGate/8.10.4.
The format (2) has been miss-implemented. It can be fixed as follows.

------------------------------------------------------------------------
*** ../delegate9.0.5/src/httpd.c	Sun Dec  4 03:56:15 2005
--- src/httpd.c	Tue Dec 27 15:19:07 2005
***************
*** 2397,2402 ****
--- 2397,2403 ----
  		dst = dstx;
  		*lengp = leng;
  		len = reqPART_TO - reqPART_FROM + 1;
+ 		len = leng;
  		if( ftell(src) == 0 ){
  			fseek(src,reqPART_FROM,0);
  			fprintf(dst,"SKIP 0 %d\r\n",len);
------------------------------------------------------------------------

A patch for a little more neat implementation including the support for
the format (3) and error handlings is enclosed.  It'll be applied to
DeleGate/9.0.6.

Cheers,
Yutaka
--
  D G   Yutaka Sato <y.sato@delegate.org> http://delegate.org/y.sato/
 ( - )  National Institute of Advanced Industrial Science and Technology
_<   >_ 1-1-4 Umezono, Tsukuba, Ibaraki, 305-8568 Japan
Do the more with the less -- B. Fuller


diff -cr ../delegate9.0.5/src/httphead.c ./src/httphead.c
*** ../delegate9.0.5/src/httphead.c	Mon Dec  5 07:43:44 2005
--- ./src/httphead.c	Tue Dec 27 13:34:15 2005
***************
*** 531,536 ****
--- 531,539 ----
  		FPRINTF(tc,"Content-Range: bytes %d-%d/%d\r\n",
  			Conn->sv.p_range[0],Conn->sv.p_range[1],Conn->sv.p_range[2]);
  	}
+ 	if( code == 416 ){
+ 		FPRINTF(tc,"Content-Range: bytes */%d\r\n",Conn->sv.p_range[2]);
+ 	}
  
  	if( tobeclosed ){
  		HTTP_clntClose(Conn,"U:unknown size internal response");
diff -cr ../delegate9.0.5/src/http.c ./src/http.c
*** ../delegate9.0.5/src/http.c	Mon Dec  5 06:40:20 2005
--- ./src/http.c	Tue Dec 27 13:59:25 2005
***************
*** 4505,4513 ****
--- 4505,4517 ----
  			}
  		}else
  		if( STRH(req,F_Range) ){
+ 			int scanHttpRange(Connection *Conn,PCStr(req),int *from,int *to);
+ 			scanHttpRange(Conn,req,&QX_range[0],&QX_range[1]);
+ 			/*
  			sscanf(req,"%*s bytes=%d-%d",&QX_range[0],&QX_range[1]);
  			Conn->cl.p_range[0] = QX_range[0];
  			Conn->cl.p_range[1] = QX_range[1];
+ 			*/
  			sv1log("#HT11 (%d) %s",QX_range[1]-QX_range[0]+1,req);
  			DontReadCache = 1;
  			DontWriteCache = 1;
diff -cr ../delegate9.0.5/src/httpd.c ./src/httpd.c
*** ../delegate9.0.5/src/httpd.c	Sun Dec  4 03:56:15 2005
--- ./src/httpd.c	Tue Dec 27 15:34:06 2005
***************
*** 2380,2390 ****
--- 2380,2429 ----
  	sv1log("relay_part(%d %d) %d/%d\n",skip,len,wcc,len);
  	return wcc;
  }
+ 
+ char *HTTP_getRequestField(Connection *Conn,PCStr(fn),PVStr(b),int bz);
+ #define reqPartFrom	Conn->cl.p_range[0]
+ #define reqPartTo	Conn->cl.p_range[1]
+ #define reqPARTIALtail	(reqPartFrom < 0 && 0 <= reqPartTo)
+ 
+ int scanHttpRange(Connection *Conn,PCStr(req),int *from,int *to){
+ 	CStr(fnam,32);
+ 	CStr(fval,128);
+ 
+ 	fieldScan(req,fnam,fval);
+ 	if( strncasecmp(fval,"bytes=",6) == 0 ){
+ 		*from = *to = 0;
+ 		sscanf(fval+6,"%d-%d",from,to);
+ 		reqPartFrom = *from;
+ 		reqPartTo   = *to;
+ 		return 0;
+ 	}
+ 	return -1;
+ }
+ 
  FILE *putPARTfilter(Connection *Conn,FILE *src,FILE *dst,int *lengp){
  	int size,len,leng;
  	FILE *dstx;
  
  	size = file_size(fileno(src));
+ 	if( reqPARTIALtail ){
+ 		/* bytes=-ddd */
+ 		reqPartFrom = size + reqPartFrom;
+ 	}
+ 	if( 0 <= reqPartFrom && reqPartTo <= 0 ){
+ 		/* bytes=ddd- */
+ 		reqPartTo = size - 1;
+ 	}
+ 	if( size <= reqPartFrom || size <= reqPartTo ){
+ 		CStr(b,128);
+ 		if(HTTP_getRequestField(Conn,"If-Range",AVStr(b),sizeof(b))){
+ 			return NULL;
+ 		}
+ 		*lengp = -1;
+ 		gotPART_SIZE = size;
+ 		return NULL;
+ 	}
+ 
  	gotPART_FROM = reqPART_FROM;
  	if( reqPART_TO <= 0 || size <= reqPART_TO )
  		gotPART_TO = size - 1;
***************
*** 2414,2421 ****
--- 2453,2464 ----
  
  	FILE *dstx = 0;
  	CStr(statb,1024);
+ /*
  	if( reqPARTIAL )
+ */
+ 	if( reqPARTIAL || reqPARTIALtail )
  	if( fp != NULL && strncasecmp(req,"HEAD ",5) != 0 ){
+ 		size = 0;
  		if( dstx = putPARTfilter(Conn,fp,tc,&size) ){
  			if( stat && *stat ){
  				int code;
***************
*** 2430,2435 ****
--- 2473,2492 ----
  			}
  			tc = dstx;
  		}
+ 		if( size < 0 ){
+ 			FILE *tmp;
+ 			stat = "416 Not satisfiable";
+ 			tmp = TMPFILE("RANGE");
+ 			fprintf(tmp,"Range not satisfiable: %d - %d\n",
+ 				reqPartFrom,reqPartTo);
+ 			fflush(tmp);
+ 			size = ftell(tmp);
+ 			fseek(tmp,0,0);
+ 			ctype = "text/html";
+ leng = putHttpMssg(Conn,tc,tmp,req,vno,serv,ctype,cenc,size,mtime,exp,stat);
+ 			fclose(tmp);
+ 			return leng;
+ 		}
  	}
  
  	if( fp != NULL )

  admin search upper oldest olders older1 this newer1 newers latest
[Top/Up] [oldest] - [Older+chunk] - [Newer+chunk] - [newest + Check]
@_@V