int parseUrlEncodedFormData()

in src/generic/formdata.c [30:197]


int parseUrlEncodedFormData(RequestData * requestData, Tcl_Interp * interp,
			    char *channelName, Tcl_Obj * len)
{
    Tcl_Obj *tclo = NULL;
    int tRes = 0;
    int listLen = -1;
    Tcl_Obj *cmdList[2];
    Tcl_Obj *uriCmd = NULL;
    Tcl_Obj *formData = NULL;
    Tcl_Channel channel;
    int mode;
    int readToEnd = 0;
    int content_length = 0;
    Tcl_DString translation;
    Tcl_DString encoding;

    channel = Web_GetChannelOrVarChannel(interp, channelName, &mode);
    if (channel == NULL) {
	LOG_MSG(interp, WRITE_LOG, __FILE__, __LINE__,
		"web::dispatch -postdata", WEBLOG_WARNING,
		"error getting channel \"", channelName, "\"", NULL);
	return TCL_ERROR;
    }

    if ((mode & TCL_READABLE) == 0) {

	LOG_MSG(interp, WRITE_LOG, __FILE__, __LINE__,
		"web::dispatch -postdata", WEBLOG_WARNING,
		"channel \"", channelName, "\" not open for reading", NULL);

	/* unregister if was a varchannel */
	Web_UnregisterVarChannel(interp, channelName, channel);

	return TCL_ERROR;
    }

    Tcl_DStringInit(&translation);
    Tcl_DStringInit(&encoding);
    Tcl_GetChannelOption(interp, channel, "-translation", &translation);
    Tcl_GetChannelOption(interp, channel, "-encoding", &encoding);
    Tcl_SetChannelOption(interp, channel, "-translation", "binary");

    /* ------------------------------------------------------------------------
     * how much to read ?
     * --------------------------------------------------------------------- */
    if (len == NULL) {

	readToEnd = 1;

    }
    else {

	if (strcmp(Tcl_GetString(len), "end") == 0) {

	    readToEnd = 1;

	}
	else {

	    readToEnd = 0;

	    if (Tcl_GetIntFromObj(interp, len, &content_length) != TCL_OK) {

		Tcl_SetChannelOption(interp, channel, "-translation", Tcl_DStringValue(&translation));
		Tcl_SetChannelOption(interp, channel, "-encoding", Tcl_DStringValue(&encoding));
		Tcl_DStringFree(&translation);
		Tcl_DStringFree(&encoding);
		/* unregister if was a varchannel */
		Web_UnregisterVarChannel(interp, channelName, channel);
		return TCL_ERROR;
	    }
	}
    }

    /* ------------------------------------------------------------------------
     * ok, read
     * --------------------------------------------------------------------- */
    formData = Tcl_NewObj();
    Tcl_IncrRefCount(formData);

    if (readToEnd) {

	/* try to read to the end  */
	/*                                         append flag */
	while (Tcl_ReadChars(channel, formData, 4096, 1) != -1) {
	    if (Tcl_Eof(channel))
		break;
	}

    }
    else {

	if (Tcl_ReadChars(channel, formData, content_length, 1) == TCL_ERROR) {

	    LOG_MSG(interp, WRITE_LOG, __FILE__, __LINE__,
		    "web::dispatch -postdata", WEBLOG_WARNING,
		    "error reading from \"", channelName, "\"", NULL);

	    Tcl_DecrRefCount(formData);

	    Tcl_SetChannelOption(interp, channel, "-translation", Tcl_DStringValue(&translation));
	    Tcl_SetChannelOption(interp, channel, "-encoding", Tcl_DStringValue(&encoding));
	    Tcl_DStringFree(&translation);
	    Tcl_DStringFree(&encoding);
	    /* unregister if was a varchannel */
	    Web_UnregisterVarChannel(interp, channelName, channel);

	    return TCL_ERROR;
	}
    }

    Tcl_SetChannelOption(interp, channel, "-translation", Tcl_DStringValue(&translation));
    Tcl_SetChannelOption(interp, channel, "-encoding", Tcl_DStringValue(&encoding));
    Tcl_DStringFree(&translation);
    Tcl_DStringFree(&encoding);
    /* unregister if was a varchannel */
    Web_UnregisterVarChannel(interp, channelName, channel);

    cmdList[0] = Tcl_NewStringObj("web::uri2list", -1);
    cmdList[1] = Tcl_DuplicateObj(formData);
    Tcl_IncrRefCount(cmdList[0]);
    Tcl_IncrRefCount(cmdList[1]);
    uriCmd = Tcl_NewListObj(2, cmdList);
    Tcl_IncrRefCount(uriCmd);
    tRes = Tcl_EvalObjEx(interp, uriCmd, TCL_EVAL_DIRECT);
    Tcl_DecrRefCount(uriCmd);
    Tcl_DecrRefCount(cmdList[0]);
    Tcl_DecrRefCount(cmdList[1]);


    Tcl_DecrRefCount(formData);

    if (tRes == TCL_ERROR) {
	LOG_MSG(interp, WRITE_LOG, __FILE__, __LINE__,
		"web::dispatch -postdata", WEBLOG_WARNING,
		"error parsing formdata", NULL);

	return TCL_ERROR;
    }

    tclo = Tcl_GetObjResult(interp);
    Tcl_IncrRefCount(tclo);
    Tcl_ResetResult(interp);

    /* --------------------------------------------------------------------------
     * only add if list length > 0
     * ----------------------------------------------------------------------- */
    if ((listLen = tclGetListLength(interp, tclo)) == -1) {
	Tcl_DecrRefCount(tclo);
	return TCL_ERROR;
    }

    if (listLen > 0) {
	/* ------------------------------------------------------------------------
	 * add list to requestData
	 * --------------------------------------------------------------------- */
	tRes = listObjAsParamList(tclo, requestData->formVarList);
	Tcl_DecrRefCount(tclo);
	return tRes;
    }

    /* --------------------------------------------------------------------------
     * done
     * ----------------------------------------------------------------------- */
    Tcl_DecrRefCount(tclo);

    return TCL_OK;
}