You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tcl.apache.org by mx...@apache.org on 2020/05/02 22:22:38 UTC

[tcl-rivet] 06/06: restructuring and testing new code of upload command

This is an automated email from the ASF dual-hosted git repository.

mxmanghi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tcl-rivet.git

commit 9b918038f2c53b3042a02c972cc662e3b6976935
Author: Massimo Manghi <mx...@apache.org>
AuthorDate: Sat May 2 02:01:22 2020 +0200

    restructuring and testing new code of upload command
---
 src/TclWeb.h                    |  37 ++++++-----
 src/mod_rivet_ng/TclWebapache.c | 133 ++++++++++++++++++++++++----------------
 src/mod_rivet_ng/rivetCore.c    | 107 ++++++++++++++------------------
 3 files changed, 146 insertions(+), 131 deletions(-)

diff --git a/src/TclWeb.h b/src/TclWeb.h
index 899eab9..f032e37 100644
--- a/src/TclWeb.h
+++ b/src/TclWeb.h
@@ -137,17 +137,17 @@ int TclWeb_PrepareUpload(char *varname, TclWebRequest *req);
  *
  * TclWeb_UploadChannel --
  *
- * Takes the address of a Tcl_Channel and uses it to create a channel
- * pointing to the upload data.
+ * It opens a new channel and sets its translation and encoding as binary
+ * The channel name is retuned as result in the interpreter pointed by req->interp
  *
  * Results:
  *
- * 'chan' points to a FileChannel containing the uploaded data.
+ * Makes the channel name available to the script level
  *
  *-----------------------------------------------------------------------------
  */
 
-int TclWeb_UploadChannel(char *varname, Tcl_Channel *chan, TclWebRequest *req);
+int TclWeb_UploadChannel(char *varname, TclWebRequest *req);
 
 /*
  *-----------------------------------------------------------------------------
@@ -166,68 +166,71 @@ int TclWeb_UploadSave(char *varname, Tcl_Obj *filename, TclWebRequest *req);
  *
  * TclWeb_UploadData --
  *
- * Fills in the 'data' Tcl_Obj with the uploaded data.
+ * Returns the uploaded data to the Tcl script level.
+ * 
+ * If the config parameter upload_files_to_var is not set the procedure
+ * returs an error
  *
  *-----------------------------------------------------------------------------
  */
 
-int TclWeb_UploadData(char *varname, Tcl_Obj *data, TclWebRequest *req);
+int TclWeb_UploadData(char *varname, TclWebRequest *req);
 
 /*
  *-----------------------------------------------------------------------------
  *
  * TclWeb_UploadSize --
  *
- * Stores, in 'sz' the size of the data uploaded.
+ * Returns the size of the data uploaded.
  *
  *-----------------------------------------------------------------------------
  */
 
-int TclWeb_UploadSize(Tcl_Obj *sz, TclWebRequest *req);
+int TclWeb_UploadSize(TclWebRequest *req);
 
 /*
  *-----------------------------------------------------------------------------
  *
  * TclWeb_UploadType --
  *
- * Stores, in 'type' the mime type of the file uploaded.
+ * Returns the mime type of the file uploaded.
  *
  *-----------------------------------------------------------------------------
  */
 
-int TclWeb_UploadType(Tcl_Obj *type, TclWebRequest *req);
+int TclWeb_UploadType(TclWebRequest *req);
 
 /*
  *-----------------------------------------------------------------------------
  *
  * TclWeb_UploadFilename --
  *
- * Get the original filename of the uploaded data, on the client side.
+ * Returns the original filename of the uploaded data, on the client side.
  *
  * Results:
  *
- * Stores the filename in 'filename'.
+ * Returns the filename to the script level
  *
  *-----------------------------------------------------------------------------
  */
 
-int TclWeb_UploadFilename(Tcl_Obj *filename, TclWebRequest *req);
+int TclWeb_UploadFilename(TclWebRequest *req);
 
 /*
  *-----------------------------------------------------------------------------
  *
  * TclWeb_UploadTempname --
  *
- * Get the name of the temp file the uploaded data was stored in.
+ * Returns the name of the temp file the uploaded data was stored in.
  *
  * Results:
  *
- * Stores the temp name in 'tempname'.
+ * the 'tempname' is returned to the script level
  *
  *-----------------------------------------------------------------------------
  */
 
-int TclWeb_UploadTempname(Tcl_Obj *tempname, TclWebRequest *req);
+int TclWeb_UploadTempname(TclWebRequest *req);
 
 /*
  *-----------------------------------------------------------------------------
@@ -243,7 +246,7 @@ int TclWeb_UploadTempname(Tcl_Obj *tempname, TclWebRequest *req);
  *-----------------------------------------------------------------------------
  */
 
-int TclWeb_UploadNames(Tcl_Obj *names, TclWebRequest *req);
+int TclWeb_UploadNames(TclWebRequest *req);
 
 int TclWeb_Escape(char *out, char *in, int len, void *var);
 
diff --git a/src/mod_rivet_ng/TclWebapache.c b/src/mod_rivet_ng/TclWebapache.c
index 98c90d5..ab87909 100644
--- a/src/mod_rivet_ng/TclWebapache.c
+++ b/src/mod_rivet_ng/TclWebapache.c
@@ -314,7 +314,7 @@ TclWeb_GetVar(Tcl_Obj *result, char *varname, int source, TclWebRequest *req)
 
     if (result->length == 0)
     {
-	return TCL_ERROR;
+	    return TCL_ERROR;
     }
 
     return TCL_OK;
@@ -334,19 +334,19 @@ TclWeb_GetVarAsList(Tcl_Obj *result, char *varname, int source, TclWebRequest *r
     while (i < j)
     {
 
-	if (!strncmp(varname, TclWeb_StringToUtf(parms[i].key, req),
-		     strlen(varname) < strlen(parms[i].key) ?
-		     strlen(parms[i].key) : strlen(varname)))
-	{
-	    Tcl_ListObjAppendElement(req->interp, result,
-				     TclWeb_StringToUtfToObj(parms[i].val, req));
-	}
-	i++;
+        if (!strncmp(varname, TclWeb_StringToUtf(parms[i].key, req),
+                 strlen(varname) < strlen(parms[i].key) ?
+                 strlen(parms[i].key) : strlen(varname)))
+        {
+            Tcl_ListObjAppendElement(req->interp, result,
+                         TclWeb_StringToUtfToObj(parms[i].val, req));
+        }
+        i++;
     }
 
     if (result == NULL)
     {
-	return TCL_ERROR;
+        return TCL_ERROR;
     }
     return TCL_OK;
 }
@@ -660,45 +660,58 @@ int TclWeb_PrepareUpload(char *varname, TclWebRequest *req)
     }
 }
 
-int TclWeb_UploadChannel(char *varname, Tcl_Channel *chan, TclWebRequest *req)
+int TclWeb_UploadChannel(char *varname, TclWebRequest *req)
 {
-    *chan = Tcl_OpenFileChannel(req->interp, req->upload->tempname, "r", 0);
+    Tcl_Channel chan;
+
+    chan = Tcl_OpenFileChannel(req->interp, req->upload->tempname, "r", 0);
     if (chan == NULL) {
 	    return TCL_ERROR;
     } else {
-        if (Tcl_SetChannelOption(req->interp,*chan,"-translation","binary") == TCL_ERROR) {
+        Tcl_Obj* result;
+
+        if (Tcl_SetChannelOption(req->interp,chan,"-translation","binary") == TCL_ERROR) {
             return TCL_ERROR;
         }
-        if (Tcl_SetChannelOption(req->interp,*chan,"-encoding","binary") == TCL_ERROR) {
+        if (Tcl_SetChannelOption(req->interp,chan,"-encoding","binary") == TCL_ERROR) {
             return TCL_ERROR;
         }
-        Tcl_RegisterChannel(req->interp, *chan);
+        Tcl_RegisterChannel(req->interp,chan);
+
+        result = Tcl_NewObj();        
+        Tcl_SetStringObj(result, Tcl_GetChannelName(chan), -1);
+        Tcl_SetObjResult(req->interp, result);
+        
         return TCL_OK;
     }
 }
 
-int TclWeb_UploadTempname(Tcl_Obj *tempname, TclWebRequest *req)
+int TclWeb_UploadTempname(TclWebRequest *req)
 {
-    Tcl_SetStringObj(tempname,
-		     TclWeb_StringToUtf(req->upload->tempname,
-					req), -1);
+    Tcl_Obj *tempname = Tcl_NewObj();
+
+    Tcl_SetStringObj(tempname,TclWeb_StringToUtf(req->upload->tempname,req), -1);
+    Tcl_SetObjResult(req->interp, tempname);
+
     return TCL_OK;
 }
 
 
 int TclWeb_UploadSave(char *varname, Tcl_Obj *filename, TclWebRequest *req)
 {
-	apr_status_t	status;
+	apr_status_t status;
+
 	status = apr_file_copy(req->upload->tempname ,Tcl_GetString(filename),APR_FILE_SOURCE_PERMS,req->req->pool);
-	if ( status == 0 ) {
+	if (status == APR_SUCCESS) {
 	    return TCL_OK;
 	} else {
 		return TCL_ERROR;
 	}
 }
 
-int TclWeb_UploadData(char *varname, Tcl_Obj *data, TclWebRequest *req)
+int TclWeb_UploadData(char *varname, TclWebRequest *req)
 {
+    Tcl_Obj* result;
     rivet_server_conf *rsc = NULL;
 
     rsc  = RIVET_SERVER_CONF( req->req->server->module_config );
@@ -706,68 +719,80 @@ int TclWeb_UploadData(char *varname, Tcl_Obj *data, TclWebRequest *req)
        get everything fixed and working first */
     if (rsc->upload_files_to_var)
     {
-	Tcl_Channel chan;
-	chan = Tcl_OpenFileChannel (req->interp, req->upload->tempname, "r", 0);
-	if (chan == NULL) {
-	    return TCL_ERROR;
-	}
-	if (Tcl_SetChannelOption(req->interp, chan,
-				 "-translation", "binary") == TCL_ERROR) {
-	    return TCL_ERROR;
-	}
-	if (Tcl_SetChannelOption(req->interp, chan,
-				 "-encoding", "binary") == TCL_ERROR) {
-	    return TCL_ERROR;
-	}
+        Tcl_Channel chan;
+        
+        chan = Tcl_OpenFileChannel (req->interp, req->upload->tempname, "r", 0);
+        if (chan == NULL) {
+            return TCL_ERROR;
+        }
+        if (Tcl_SetChannelOption(req->interp, chan,
+                     "-translation", "binary") == TCL_ERROR) {
+            return TCL_ERROR;
+        }
+        if (Tcl_SetChannelOption(req->interp, chan,
+                     "-encoding", "binary") == TCL_ERROR) {
+            return TCL_ERROR;
+        }
 
-	/* Put data in a variable  */
-	Tcl_ReadChars(chan, data, (int)ApacheUpload_size(req->upload), 0);
-	if (Tcl_Close(req->interp, chan) == TCL_ERROR) {
-	    return TCL_ERROR;
-	}
+        /* Put data in a variable  */
+        result = Tcl_NewObj();
+        Tcl_ReadChars(chan, result, (int)ApacheUpload_size(req->upload), 0);
+        if (Tcl_Close(req->interp, chan) == TCL_ERROR) {
+            return TCL_ERROR;
+        }
+        
+        Tcl_SetObjResult(req->interp, result);
     } else {
-	Tcl_AppendResult(req->interp,
-			 "RivetServerConf UploadFilesToVar is not set", NULL);
-	return TCL_ERROR;
+        Tcl_AppendResult(req->interp,
+                 "RivetServerConf UploadFilesToVar is not set", NULL);
+        return TCL_ERROR;
     }
+    
     return TCL_OK;
 }
 
-int TclWeb_UploadSize(Tcl_Obj *sz, TclWebRequest *req)
+int TclWeb_UploadSize(TclWebRequest *req)
 {
-    Tcl_SetIntObj(sz, (int)ApacheUpload_size(req->upload));
+    Tcl_Obj* result = Tcl_NewObj();
+    Tcl_SetIntObj(result, (int)ApacheUpload_size(req->upload));
+    Tcl_SetObjResult(req->interp, result);
     return TCL_OK;
 }
 
-int TclWeb_UploadType(Tcl_Obj *type, TclWebRequest *req)
+int TclWeb_UploadType(TclWebRequest *req)
 {
+    Tcl_Obj *type = Tcl_NewObj();
+
     /* If there is a type, return it, if not, return blank. */
     Tcl_SetStringObj(type, ApacheUpload_type(req->upload)
 		     ? (char *)ApacheUpload_type(req->upload) : (char *)"", -1);
+
+    Tcl_SetObjResult(req->interp, type);
     return TCL_OK;
 }
 
-int TclWeb_UploadFilename(Tcl_Obj *filename, TclWebRequest *req)
+int TclWeb_UploadFilename(TclWebRequest *req)
 {
-    Tcl_SetStringObj(filename,
-		     TclWeb_StringToUtf(req->upload->filename,
-					req), -1);
+    Tcl_Obj *filename = Tcl_NewObj();
+    Tcl_SetStringObj(filename,TclWeb_StringToUtf(req->upload->filename,req), -1);
+
+    Tcl_SetObjResult(req->interp, filename);
     return TCL_OK;
 }
 
-int TclWeb_UploadNames(Tcl_Obj *names, TclWebRequest *req)
+int TclWeb_UploadNames(TclWebRequest *req)
 {
     ApacheUpload *upload;
+    Tcl_Obj      *names = Tcl_NewObj();
 
     upload = ApacheRequest_upload(req->apachereq);
     while (upload)
     {
-        Tcl_ListObjAppendElement(
-            req->interp, names,
-            TclWeb_StringToUtfToObj(upload->name,req));
+        Tcl_ListObjAppendElement(req->interp,names,TclWeb_StringToUtfToObj(upload->name,req));
         upload = upload->next;
     }
 
+    Tcl_SetObjResult(req->interp,names);
     return TCL_OK;
 }
 
diff --git a/src/mod_rivet_ng/rivetCore.c b/src/mod_rivet_ng/rivetCore.c
index ff9abba..1537638 100644
--- a/src/mod_rivet_ng/rivetCore.c
+++ b/src/mod_rivet_ng/rivetCore.c
@@ -1039,13 +1039,10 @@ TCL_CMD_HEADER( Rivet_Upload )
 {
     char*   varname = NULL;
     int     subcommandindex;
-    int     upload_prepared = 0;
-
-    Tcl_Obj* result = NULL;
 
     /* ::rivet::upload subcommands must register
-     * 
-     * - subcommand definition 
+     *
+     * - subcommand definition
      * - subcommand integer progressive index
      * - subcommand required (minimum) number of arguments
      *
@@ -1116,90 +1113,80 @@ TCL_CMD_HEADER( Rivet_Upload )
         Tcl_AppendObjToErrorInfo(interp, infoobj);
         Tcl_DecrRefCount(infoobj);
 
-        Tcl_WrongNumArgs(interp, objc, objv, "uploadname");
+        if (subcommandindex == SAVE) {
+            Tcl_WrongNumArgs(interp, 2, objv, "uploadname filename");
+        } else {
+            Tcl_WrongNumArgs(interp, objc, objv, "uploadname");
+        }
         return TCL_ERROR;
-    } 
+    }
 
     /* We check whether an upload with a given name exists */
 
     if (objc >= 3) {
+        int tcl_status;
         varname = Tcl_GetString(objv[2]);
 
         /* TclWeb_PrepareUpload calls ApacheUpload_find and returns
          * TCL_OK if the named upload exists in the current request */
+        tcl_status = TclWeb_PrepareUpload(varname, private->req);
 
-        if (TclWeb_PrepareUpload(varname, private->req) != TCL_OK)
+        if (subcommandindex == EXISTS) {
+            Tcl_Obj* result = NULL;
+            int upload_prepared = 0;
+
+            if (tcl_status == TCL_OK) upload_prepared = 1;
+
+            result = Tcl_NewObj();
+            Tcl_SetIntObj(result,upload_prepared);
+            Tcl_SetObjResult(interp, result);
+            return TCL_OK;
+                
+        }
+
+        if (tcl_status != TCL_OK)
         {
             Tcl_AddErrorInfo(interp, "Unable to find the upload named '");
             Tcl_AppendObjToErrorInfo(interp,Tcl_NewStringObj(varname,-1));
             Tcl_AppendObjToErrorInfo(interp,Tcl_NewStringObj("'",-1));
             return TCL_ERROR;
-        } 
-        upload_prepared = 1;
+        }
     }
 
-    result = Tcl_NewObj();
+    /* CHANNEL  : get the upload channel name
+     * SAVE     : save data to a specified filename
+     * DATA     : get the uploaded data into a Tcl variable
+     * SIZE     : uploaded data size
+     * TYPE     : upload mimetype
+     * FILENAME : upload original filename
+     * TEMPNAME : temporary file where the upload is taking place
+     * NAMES    : list of uploads
+     *
+     * the procedure shouldn't reach for the default case
+     */
 
     switch ((enum subcommand)subcommandindex)
     {
-        case CHANNEL: {
-            Tcl_Channel chan;
-            char *channelname = NULL;
-
-            if (TclWeb_UploadChannel(varname, &chan, private->req) != TCL_OK) {
-                return TCL_ERROR;
-            }
-            channelname = (char *)Tcl_GetChannelName(chan);
-            Tcl_SetStringObj(result, channelname, -1);
-            break;
-        }
+        case CHANNEL:
+            return TclWeb_UploadChannel(varname, private->req);
         case SAVE:
-            /* save data to a specified filename  */
-            if (objc != 4) {
-                Tcl_WrongNumArgs(interp, 2, objv, "uploadname filename");
-                return TCL_ERROR;
-            }
-
-            if (TclWeb_UploadSave(varname, objv[3], private->req) != TCL_OK)
-            {
-                return TCL_ERROR;
-            }
-            break;
+            return TclWeb_UploadSave(varname, objv[3], private->req);
         case DATA:
-            if (TclWeb_UploadData(varname, result, private->req) != TCL_OK) {
-                return TCL_ERROR;
-            }
-            break;
-        case EXISTS: {
-            Tcl_SetIntObj(result,upload_prepared);
-            break;
-        }
+            return TclWeb_UploadData(varname, private->req);
         case SIZE:
-            TclWeb_UploadSize(result, private->req);
-            break;
+            return TclWeb_UploadSize(private->req);
         case TYPE:
-            TclWeb_UploadType(result, private->req);
-            break;
+            return TclWeb_UploadType(private->req);
         case FILENAME:
-            TclWeb_UploadFilename(result, private->req);
-            break;
+            return TclWeb_UploadFilename(private->req);
         case TEMPNAME:
-            TclWeb_UploadTempname(result,private->req);
-            break;
+            return TclWeb_UploadTempname(private->req);
         case NAMES:
-            if (objc != 2)
-            {
-                Tcl_WrongNumArgs(interp, 1, objv, "names");
-                return TCL_ERROR;
-            }
-            TclWeb_UploadNames(result, private->req);
-            break;
+            return TclWeb_UploadNames(private->req);
         default:
-            Tcl_WrongNumArgs(interp, 1, objv,
-                             "channel|save ?name?|data|exists|size|type|filename|names|tempname");
+            Tcl_WrongNumArgs(interp, 1, objv,"Rivet internal error: inconsistent argument");
     }
-    Tcl_SetObjResult(interp, result);
-    return TCL_OK;
+    return TCL_ERROR;
 }
 
 /*


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tcl.apache.org
For additional commands, e-mail: commits-help@tcl.apache.org