httpd-apreq-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject cvs commit: httpd-apreq/c apache_request.c apache_request.h
Date Sat, 02 Jun 2001 13:41:25 GMT
joes        01/06/02 06:41:24

  Modified:    Request  Request.pm Request.xs
               c        apache_request.c apache_request.h
  Log:
  SFIO support via perl Makefile.PL DEFINE=-DSFIO
  Upload hooks added.
  
  Revision  Changes    Path
  1.16      +23 -0     httpd-apreq/Request/Request.pm
  
  Index: Request.pm
  ===================================================================
  RCS file: /home/cvs/httpd-apreq/Request/Request.pm,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- Request.pm	2001/04/02 22:44:57	1.15
  +++ Request.pm	2001/06/02 13:41:21	1.16
  @@ -97,6 +97,29 @@
    my $upload = $apr->upload('file');
    $upload->link("/home/user/myfile") || warn "link failed: $!";
   
  +=item HOOK_DATA
  +
  +Extra configuration info to be passed to and upload hook.
  +See next item for details.
  +
  +=item UPLOAD_HOOK
  +
  +Sets up a callback to run whenever file upload data is read. This
  +can be used to provide an upload progress meter during file uploads.
  +Apache will automatically continue writing the original data to
  +$upload->fh after the hook exits.
  +
  + my $transparent_hook = sub {
  +   my ($upload, $buf, $len, $hook_data) = @_;
  +   warn "$hook_data: got $len bytes for " . $upload->name;
  + };
  +
  + my $apr = Apache::Request->new($r, 
  +                                HOOK_DATA => "Note",
  +                                UPLOAD_HOOK => $transparent_hook,
  +                               );
  + $apr->parse;
  +
   =back
   
   =head2 instance
  
  
  
  1.15      +94 -13    httpd-apreq/Request/Request.xs
  
  Index: Request.xs
  ===================================================================
  RCS file: /home/cvs/httpd-apreq/Request/Request.xs,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- Request.xs	2001/05/18 17:31:05	1.14
  +++ Request.xs	2001/06/02 13:41:21	1.15
  @@ -70,13 +70,17 @@
   
   typedef ApacheRequest * Apache__Request;
   typedef ApacheUpload  * Apache__Upload;
  +typedef struct { 
  +	SV* data;
  +	SV* sub; 
  +	} Hook;
   
   #define ApacheUpload_fh(upload)       upload->fp
   #define ApacheUpload_size(upload)     upload->size
   #define ApacheUpload_name(upload)     upload->name
   #define ApacheUpload_filename(upload) upload->filename
   #define ApacheUpload_next(upload)     upload->next
  -#define ApacheUpload_tempname(upload)   upload->tempname
  +#define ApacheUpload_tempname(upload) upload->tempname
   
   #ifndef PerlLIO_dup
   #define PerlLIO_dup(fd)   dup((fd)) 
  @@ -90,6 +94,7 @@
   #else
   typedef FILE * InputStream;
   #define PerlIO_importFILE(fp,flags) fp
  +#define PerlIO_write(a,b,c)  fwrite((b),1,(c),(a))
   #endif
   
   static char *r_keys[] = { "_r", "r", NULL };
  @@ -140,6 +145,52 @@
       return sv; 
   } 
   
  +static int upload_hook(void *ptr, char *buf, int len, ApacheUpload *upload)
  +{
  +    Hook *hook = (Hook*) ptr;
  +
  +    if ( upload->fp == NULL && ! ApacheRequest_tmpfile(upload->req, upload)
)
  +	    return -1; /* error */
  +
  +    {
  +    	dTARG;
  +    	dSP;
  +
  +    	PUSHMARK(SP);
  +    	EXTEND(SP, 4);
  +        ENTER;
  +    	SAVETMPS;
  +
  +    	TARG = sv_newmortal();
  +    	sv_setref_pv( TARG, "Apache::Upload", (void*)upload );
  +    	PUSHTARG;
  +
  +    	TARG = sv_2mortal( newSVpvn(buf,len) );
  +    	SvTAINT(TARG);
  +    	PUSHTARG;
  +
  +    	TARG = sv_2mortal( newSViv(len) );
  +    	SvTAINT(TARG);
  +    	PUSHTARG;
  +
  +    	PUSHs(hook->data);
  +
  +    	PUTBACK;
  +    	perl_call_sv(hook->sub, G_EVAL|G_DISCARD);
  +    	FREETMPS;
  +    	LEAVE;
  +    }
  +
  +    return SvTRUE(ERRSV) ? -1 : PerlIO_write(upload->fp, buf, len);
  +}
  +
  +static void clear_hook(void *ptr) {
  +   Hook *hook = (Hook*) ptr;
  +   hook->sub != Nullsv && sv_2mortal(hook->sub);
  +   hook->data != Nullsv && sv_2mortal(hook->data);
  +}
  +
  +
   #define upload_push(upload) \
       XPUSHs(sv_2mortal(upload_bless(upload))) 
   
  @@ -156,6 +207,7 @@
   		    GvNAME(handle), GvNAMELEN(handle), G_DISCARD);
   }
   
  +
   #ifdef CGI_COMPAT
   static void register_uploads (ApacheRequest *req) {
       ApacheUpload *upload;
  @@ -189,7 +241,7 @@
       PREINIT:
       int i;
       SV *robj;
  -
  +	
       CODE:
       class = class; /* -Wall */ 
       robj = ST(1);
  @@ -204,6 +256,17 @@
   		RETVAL->disable_uploads = (int)SvIV(ST(i+1));
   		break;
   	    }
  +
  +	case 'h':
  +	   if (strcasecmp(key, "hook_data") == 0) {
  +		if (RETVAL->hook_data == NULL) {
  +		  RETVAL->hook_data = (void *)ap_pcalloc(r->pool, sizeof(Hook));
  +		  ((Hook*)RETVAL->hook_data)->sub = Nullsv;
  + 		}
  +		((Hook*)RETVAL->hook_data)->data = newSVsv(ST(i+1));	
  +		break;
  +	   }
  +
   	case 'p':
   	    if (strcasecmp(key, "post_max") == 0) {
   		RETVAL->post_max = (int)SvIV(ST(i+1));
  @@ -214,16 +277,31 @@
   		RETVAL->temp_dir = (char *)SvPV(ST(i+1), PL_na);
   		break;
   	    }
  +	case 'u':
  +	    if (strcasecmp(key, "upload_hook") == 0) {
  +		if (RETVAL->hook_data == NULL) {
  +		  RETVAL->hook_data = (void *)ap_pcalloc(r->pool, sizeof(Hook));
  +	          ((Hook*)RETVAL->hook_data)->data = Nullsv;
  + 		}
  +		((Hook*)RETVAL->hook_data)->sub = newSVsv(ST(i+1));
  +		RETVAL->upload_hook = &upload_hook;
  +		break;
  +	    }
   	default:
   	    croak("[libapreq] unknown attribute: `%s'", key);
   	}
       }
   
  +
       OUTPUT:
       RETVAL
   
       CLEANUP:
       apreq_add_magic(ST(0), robj, RETVAL);
  +    if ( RETVAL->hook_data != NULL ) {
  +    	ap_register_cleanup(r->pool, RETVAL->hook_data, 
  +			   clear_hook, ap_null_cleanup);    
  +    }
   
   char *
   ApacheRequest_script_name(req)
  @@ -347,7 +425,9 @@
           req->upload = (ApacheUpload *)SvIV((SV*)SvRV(sv));
           XSRETURN_EMPTY;
       }
  -    ApacheRequest_parse(req);
  +
  +    if ( !req->parsed ) ApacheRequest_parse(req);
  +
       if (GIMME == G_SCALAR) {
           STRLEN n_a;
           char *name = sv ? SvPV(sv, n_a) : NULL;
  @@ -383,28 +463,29 @@
       Apache::Upload upload
   
       CODE:
  -    if (!(RETVAL = PerlIO_importFILE(ApacheUpload_fh(upload),0))) {
  -	XSRETURN_UNDEF;
  -    }
  +    if (  ( RETVAL = ApacheUpload_fh(upload) ) == NULL  )
  +	    XSRETURN_UNDEF;
   
       OUTPUT:
       RETVAL
   
       CLEANUP:
  -    if (ST(0) != &sv_undef) {
  -	IO *io = GvIOn((GV*)SvRV(ST(0))); 
  +    if (ST(0) != &PL_sv_undef) {
  +	IO *io = GvIOn((GV*)SvRV(ST(0)));
   	int fd = PerlIO_fileno(IoIFP(io));
   	PerlIO *fp;
   
  -	fd = PerlLIO_dup(fd); 
  +	fd = PerlLIO_dup(fd);
   	if (!(fp = PerlIO_fdopen(fd, "r"))) { 
   	    PerlLIO_close(fd);
   	    croak("fdopen failed!");
  -	} 
  -	PerlIO_seek(fp, 0, 0); 
  -	IoIFP(GvIOn((GV*)SvRV(ST(0)))) = fp;
  +	}
  +	if (upload->req->parsed)
  +	    PerlIO_seek(fp, 0, 0);
  +
  +	IoIFP(GvIOn((GV*)SvRV(ST(0)))) = fp;  	
   	ap_register_cleanup(upload->req->r->pool, (void*)SvRV(ST(0)), 
  -			    apreq_close_handle, ap_null_cleanup);    
  +			    apreq_close_handle, ap_null_cleanup);      
       }
   
   long
  
  
  
  1.11      +25 -15    httpd-apreq/c/apache_request.c
  
  Index: apache_request.c
  ===================================================================
  RCS file: /home/cvs/httpd-apreq/c/apache_request.c,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- apache_request.c	2001/03/15 15:05:35	1.10
  +++ apache_request.c	2001/06/02 13:41:23	1.11
  @@ -268,9 +268,8 @@
   int ApacheRequest___parse(ApacheRequest *req)
   {
       request_rec *r = req->r;
  +    int result;
   
  -    req->parsed = 1;
  -
       if (r->args) {
           split_to_parms(req, r->args);
       }
  @@ -278,20 +277,24 @@
       if (r->method_number == M_POST) { 
   	const char *ct = ap_table_get(r->headers_in, "Content-type"); 
   	if (ct && strcaseEQN(ct, DEFAULT_ENCTYPE, DEFAULT_ENCTYPE_LENGTH)) {
  -	    return ApacheRequest_parse_urlencoded(req); 
  +	    result = ApacheRequest_parse_urlencoded(req); 
   	}
   	else if (ct && strcaseEQN(ct, MULTIPART_ENCTYPE, MULTIPART_ENCTYPE_LENGTH)) {
  -	   return ApacheRequest_parse_multipart(req); 
  +	   result = ApacheRequest_parse_multipart(req); 
   	}
   	else {
   	    ap_log_rerror(REQ_ERROR, 
   			  "[libapreq] unknown content-type: `%s'", ct); 
  -	    return HTTP_INTERNAL_SERVER_ERROR;
  +	    result = HTTP_INTERNAL_SERVER_ERROR;
   	}
       } 
       else {
  -	return ApacheRequest_parse_urlencoded(req); 
  +	result = ApacheRequest_parse_urlencoded(req); 
       }
  +
  +    req->parsed = 1;
  +    return result;
  +
   }
   
   int ApacheRequest_parse_urlencoded(ApacheRequest *req)
  @@ -319,8 +322,17 @@
   }
   
   static void remove_tmpfile(void *data) {
  -    remove((char *) data);
  -    free((char *) data);
  +    ApacheUpload *upload = (ApacheUpload *) data;
  +    ApacheRequest *req = upload->req;
  +
  +    if( ap_pfclose(req->r->pool, upload->fp) )
  +	ap_log_rerror(REQ_ERROR,
  +		      "[libapreq] close error on '%s'", upload->tempname);	
  +    if( remove(upload->tempname) )
  +	ap_log_rerror(REQ_ERROR,
  +		      "[libapreq] remove error on '%s'", upload->tempname);
  +
  +    free(upload->tempname);
   }
   
   FILE *ApacheRequest_tmpfile(ApacheRequest *req, ApacheUpload *upload)
  @@ -332,7 +344,8 @@
       int fd, tries = 100;
       
       while (--tries > 0) {
  -	if ( (name = tempnam(req->temp_dir, prefix)) == NULL ) continue;
  +	if ( (name = tempnam(req->temp_dir, prefix)) == NULL )
  +	    continue;
   	fd = ap_popenf(r->pool, name, O_CREAT|O_EXCL|O_RDWR, 0600);
   	if ( fd >= 0 )
   	    break; /* success */
  @@ -340,7 +353,7 @@
   	    free(name);
       }
       
  -    if ( tries == 0  || (fp = ap_pfdopen(r->pool, fd, "w+") ) == NULL ) {
  +    if ( tries == 0  || (fp = ap_pfdopen(r->pool, fd, "wb+") ) == NULL ) {
   	ap_log_rerror(REQ_ERROR,
   		      "[libapreq] could not open temp file '%s'", name); 	
   	if ( fd >= 0 ) { remove(name); free(name); }
  @@ -349,7 +362,7 @@
   
       upload->fp = fp;
       upload->tempname = name;
  -    ap_register_cleanup(r->pool, (void *)upload->tempname, 
  +    ap_register_cleanup(r->pool, (void *)upload, 
   			remove_tmpfile, ap_null_cleanup);
       return fp;
   
  @@ -462,11 +475,8 @@
   		upload->size += wlen;
   	    }
   
  -	    if (upload->size > 0 && (req->upload_hook == NULL)) {
  +	    if (upload->size > 0 && (upload->fp != NULL)) {
   		fseek(upload->fp, 0, 0);
  -	    }
  -	    else {
  -		upload->fp = NULL;
   	    }
   	}
       }
  
  
  
  1.6       +23 -1     httpd-apreq/c/apache_request.h
  
  Index: apache_request.h
  ===================================================================
  RCS file: /home/cvs/httpd-apreq/c/apache_request.h,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- apache_request.h	2001/03/15 03:04:13	1.5
  +++ apache_request.h	2001/06/02 13:41:23	1.6
  @@ -10,6 +10,28 @@
   #include "http_protocol.h"
   #include "util_script.h"
   
  +#ifdef  SFIO
  +#include "sfio.h"
  +
  +/* sfio 2000 changed _stdopen to _stdfdopen */
  +#if SFIO_VERSION >= 20000101L
  +#define _stdopen _stdfdopen
  +#endif
  +
  +extern Sfio_t*  _stdopen _ARG_((int, const char*)); /*1999*/
  +
  +#undef  FILE
  +#define FILE 			Sfio_t
  +#undef  fwrite
  +#define fwrite(p,s,n,f)		sfwrite((f),(p),(s)*(n))
  +#undef  fseek
  +#define fseek(f,a,b)		sfseek((f),(a),(b))
  +#undef  ap_pfdopen
  +#define ap_pfdopen(p,q,r) 	_stdopen((q),(r))
  +#undef  ap_pfclose
  +#define ap_pfclose(p,q)		sfclose(q)
  +#endif /*SFIO*/
  +
   typedef struct ApacheUpload ApacheUpload;
   
   typedef struct {
  @@ -19,7 +41,7 @@
       int parsed;
       int post_max;
       int disable_uploads;
  -    int (*upload_hook)(void *ptr, char *buf, int len, const ApacheUpload *upload);
  +    int (*upload_hook)(void *ptr, char *buf, int len, ApacheUpload *upload);
       void *hook_data;
       char* temp_dir;
       request_rec *r;
  
  
  

Mime
View raw message