int mimeSplitMultipart()

in src/generic/formdata.c [266:448]


int mimeSplitMultipart(Tcl_Interp * interp, Tcl_Channel channel,
		       const char *boundary, RequestData * requestData)
{

    Tcl_Obj *pro = NULL;
    Tcl_Obj *hdr = NULL;
    Tcl_Obj *bdy = NULL;
    int isLast = TCL_ERROR;
    long upLoadFileSize = 0;
    long bytesSkipped = 0;
    Tcl_Obj *tmpFileName = NULL;

    MimeContDispData *mimeContDispData = NULL;

    isLast = TCL_ERROR;

/*   printf("DBG mimeSplitMultipart - starting\n"); fflush(stdout); */

    /* --------------------------------------------------------------------------
     * prolog
     * ----------------------------------------------------------------------- */
    pro = Tcl_NewObj();
    if (pro == NULL)
	return TCL_ERROR;
    Tcl_IncrRefCount(pro);
    mimeReadBody(channel, pro, boundary, &isLast);
/*   printf("DBG prolog: %s\n",Tcl_GetString(pro)); fflush(stdout); */
    Tcl_DecrRefCount(pro);

    /* --------------------------------------------------------------------------
     * read until last
     * ----------------------------------------------------------------------- */

    /* fixme: only read content_length bytes ... */
    /* For now (3.5) we will add this to the documentation. */
    while (isLast == TCL_ERROR) {

	/* ------------------------------------------------------------------------
	 * header
	 * --------------------------------------------------------------------- */
	hdr = Tcl_NewObj();
	if (hdr == NULL)
	    return TCL_ERROR;
	Tcl_IncrRefCount(hdr);
	mimeReadHeader(channel, hdr);
	mimeContDispData =
	    mimeGetContDispFromHeader(interp, Tcl_GetString(hdr));
	Tcl_DecrRefCount(hdr);

	/* ------------------------------------------------------------------------
	 * body
	 * --------------------------------------------------------------------- */
	if (mimeContDispData == NULL) {
	    LOG_MSG(interp, WRITE_LOG, __FILE__, __LINE__,
		    "web::dispatch -postdata",
		    WEBLOG_ERROR,
		    "error accessing 'Content-Disposition'. Check boundary",
		    NULL);
	    return TCL_ERROR;
	}

	if ((mimeContDispData->name == NULL) ||
	    (mimeContDispData->type == NULL)) {

	    destroyMimeContDispData(mimeContDispData);
	    return TCL_ERROR;
	}

	if (STRCASECMP(mimeContDispData->type, "form-data") == 0) {

	    /* ----------------------------------------------------------------------
	     * file upload ?
	     * ------------------------------------------------------------------- */

	    if (mimeContDispData->fileName != NULL) {

		int fileNameLen = strlen(mimeContDispData->fileName);
		int flag = TCL_OK;
		Tcl_Obj *lobjv[4];
		Tcl_Obj *fileUploadList = NULL;

		WebGetLong(interp, requestData->upLoadFileSize,
			   upLoadFileSize, flag);
		if (flag == TCL_ERROR) {
		    destroyMimeContDispData(mimeContDispData);
		    return TCL_ERROR;
		}

		bytesSkipped = 0;

		tmpFileName = tempFileName(interp, requestData, NULL, NULL);
		if (tmpFileName == NULL) {
		    LOG_MSG(interp, WRITE_LOG, __FILE__, __LINE__,
			    "web::dispatch -postdata",
			    WEBLOG_ERROR,
			    "cannot request name for temporary file", NULL);
		    destroyMimeContDispData(mimeContDispData);
		    return TCL_ERROR;
		}

		readAndDumpBody(interp, channel, boundary, &isLast,
				tmpFileName, upLoadFileSize,
				requestData->filePermissions, &bytesSkipped);

		if (fileNameLen > 0) {

		    lobjv[0] = tmpFileName;
		    lobjv[1] =
			Tcl_NewStringObj(mimeContDispData->fileName, -1);
		    if (upLoadFileSize == 0)
			lobjv[2] = Tcl_NewIntObj(-1);
		    else
			lobjv[2] = Tcl_NewLongObj(bytesSkipped);
		    lobjv[3] =
			Tcl_NewStringObj(mimeContDispData->content, -1);

		}
		else {

		    lobjv[0] = Tcl_NewStringObj("", -1);
		    lobjv[1] = Tcl_NewStringObj("", -1);
		    lobjv[2] = Tcl_NewIntObj(-2);
		    lobjv[3] = Tcl_NewStringObj("", -1);
		}

		fileUploadList = Tcl_NewObj();
		Tcl_IncrRefCount(fileUploadList);
		Tcl_ListObjReplace(interp, fileUploadList, 0, 0, 4, lobjv);

		if (paramListAdd(requestData->formVarList,
				 mimeContDispData->name, fileUploadList)
		    == TCL_ERROR) {
		    LOG_MSG(interp, WRITE_LOG, __FILE__, __LINE__,
			    "web::dispatch -postdata",
			    WEBLOG_ERROR,
			    "cannot add \"",
			    mimeContDispData->name, ", ",
			    Tcl_GetString(fileUploadList),
			    "\" to web::formvar data", NULL);

		    Tcl_ListObjReplace(interp, fileUploadList, 0, 3, 0, NULL);
		    Tcl_DecrRefCount(fileUploadList);

		    destroyMimeContDispData(mimeContDispData);
		    return TCL_ERROR;
		}
		Tcl_DecrRefCount(fileUploadList);
	    }
	    else {

		/* --------------------------------------------------------------------
		 * no filename. is normal field
		 * ----------------------------------------------------------------- */
		bdy = Tcl_NewObj();
		if (bdy == NULL) {
		    destroyMimeContDispData(mimeContDispData);
		    return TCL_ERROR;
		}
		Tcl_IncrRefCount(bdy);
		mimeReadBody(channel, bdy, boundary, &isLast);

/*         printf("DBG mimeSplitMultipart - '%s' -> '%s'\n",mimeContDispData->name,Tcl_GetString(bdy)); fflush(stdout); */

		if (paramListAdd(requestData->formVarList,
				 mimeContDispData->name, bdy)
		    == TCL_ERROR) {
		    LOG_MSG(interp, WRITE_LOG, __FILE__, __LINE__,
			    "web::dispatch -postdata", WEBLOG_ERROR,
			    "cannot add \"",
			    mimeContDispData->name, ", ",
			    Tcl_GetString(bdy),
			    "\" to web::formvar data", NULL);
		    destroyMimeContDispData(mimeContDispData);
		    Tcl_DecrRefCount(bdy);
		    return TCL_ERROR;
		}
		Tcl_DecrRefCount(bdy);
	    }
	}
	destroyMimeContDispData(mimeContDispData);
    }
    return TCL_OK;
}