New functions for parsing get & post requests

Kuzin Andrey <[email protected]>
Newsgroups gmane.comp.web.fastcgi.devel,gmane.spam.detected
Message-ID <[email protected]>
Hello list ! I'm a new member.

I use fastcgi in built-in admin page for my pthreads
application. Library don't have any functions for
processing get & post requests and i decide to
write some of them.
I think it will be very useful for all library users.


Example of usage:
=========================
FCGX_Request request;
const char *cs, *cs1, *cs2;
....

FCGX_InitRequest(&request, fastcgi_socket, 0);
for (;;)
{
   pthread_mutex_lock(&accept_mutex);
   rc = FCGX_Accept_r(&request);
   pthread_mutex_unlock(&accept_mutex);
 
   // this is my new function
   FCGX_PrepareRequestVars(&request);

   // find "list" in QUERY_STRING for GET request
   cs1 = FCGX_GetParam("list", request.getp);

   // find "list" in POST request
   cs2 = FCGX_GetParam("list", request.postp);

   .....
   FCGX_Finish_r(&request);
   continue;
};

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Kuzin Andrey  -  [email protected]
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

_______________________________________________
FastCGI-developers mailing list
FastCGI-developers-xGejAJT2w6xVgU18Zptdi0EOCMrvLtNR@public.gmane.org
http://mailman.pins.net/mailman/listinfo.cgi/fastcgi-developers
fcgiapp-h.patch (application/octet-stream, 1.2 KB)
diff --git a/include/fcgiapp.h b/include/fcgiapp.h
index d7236f6..b0cff68 100644
--- a/include/fcgiapp.h
+++ b/include/fcgiapp.h
@@ -94,11 +94,15 @@ typedef struct FCGX_Request {
     FCGX_Stream *in;
     FCGX_Stream *out;
     FCGX_Stream *err;
-	char **envp;
+    FCGX_ParamArray envp;
+    FCGX_ParamArray getp;
+    FCGX_ParamArray postp;
 
 	/* Don't use anything below here */
 
     struct Params *paramsPtr;
+    struct Params *getParamsPtr;
+    struct Params *postParamsPtr;
     int ipcFd;               /* < 0 means no connection */
     int isBeginProcessed;     /* FCGI_BEGIN_REQUEST seen */
     int keepConnection;       /* don't close ipcFd at end of request */
@@ -615,6 +619,18 @@ DLLAPI void FCGX_FreeStream(FCGX_Stream **stream);
  */
 DLLAPI void FCGX_ShutdownPending(void);
 
+/*
+*----------------------------------------------------------------------
+*
+* FCGX_PrepareRequestVars --
+*
+*     Prepare form data variables from HTTP GET & POST.
+*
+*     Returns 0 upon success.
+*----------------------------------------------------------------------
+*/
+DLLAPI int FCGX_PrepareRequestVars(FCGX_Request *request);
+
 #if defined (__cplusplus) || defined (c_plusplus)
 } /* terminate extern "C" { */
 #endif
fcgiapp-c.patch (application/octet-stream, 4 KB)
diff --git a/libfcgi/fcgiapp.c b/libfcgi/fcgiapp.c
index 178cfe4..254aa7a 100644
--- a/libfcgi/fcgiapp.c
+++ b/libfcgi/fcgiapp.c
@@ -2029,6 +2029,8 @@ void FCGX_Free(FCGX_Request * request, int close)
     FCGX_FreeStream(&request->out);
     FCGX_FreeStream(&request->err);
     FreeParams(&request->paramsPtr);
+    FreeParams(&request->getParamsPtr);
+    FreeParams(&request->postParamsPtr);
 
     if (close) {
         OS_IpcClose(request->ipcFd);
@@ -2252,6 +2254,10 @@ TryAgain:
     reqDataPtr->err = NewWriter(reqDataPtr, 512, FCGI_STDERR);
     reqDataPtr->nWriters = 2;
     reqDataPtr->envp = reqDataPtr->paramsPtr->vec;
+    reqDataPtr->getp = NULL;
+    reqDataPtr->postp = NULL;
+    reqDataPtr->getParamsPtr = NULL;
+    reqDataPtr->postParamsPtr = NULL;
     return 0;
 }
 
@@ -2307,3 +2313,111 @@ void FCGX_SetExitStatus(int status, FCGX_Stream *stream)
     data->reqDataPtr->appStatus = status;
 }
 
+#define MAX_PARAM_NUM 100
+ParamsPtr GenerateParamFromWebEscapedString(char *data){
+    ParamsPtr paramsPtr = NewParams(MAX_PARAM_NUM);
+
+    char *p, *r, *param, hex1, hex2;
+    int counter=0;
+    int parser_mode=0;
+
+    if (!data || !paramsPtr) return NULL;
+
+    for (p=r=param=data; *p; p++) {
+	switch (parser_mode) {
+	    case 0: // parsing name of variable or value
+		if (*p == '%') { parser_mode = 1; break; } // get hex1 value
+		if (*p == '+') { *r=' '; r++; break; }
+		if (*p == '&') {
+		    // add next parameter
+		    *r++=0;
+		    if (counter < MAX_PARAM_NUM) {
+			PutParam(paramsPtr, StringCopy(param));
+			param = r;
+			counter++;
+		    } else {
+			parser_mode=3; // skip all another data (no more space in paramsPtr)
+		    };
+		    break;
+		}
+		*r++ = *p;
+		break;
+	    case 1: // get first hex char from %-escaped char
+		hex1 =  toupper(*p);
+		if (hex1 - '0' < 10)
+		    hex1 -= '0';
+		else
+		    hex1 = hex1 + 10 - 'A';
+		parser_mode = 2; // get hex2 value
+		break;
+	    case 2: //get hex2 value
+		hex2 =  toupper(*p);
+		if (hex2 - '0' < 10)
+		    hex2 -= '0';
+		else
+		    hex2 = hex2 + 10 - 'A';
+		*r++ = (hex1 << 4) + hex2;
+		parser_mode = 0; // return to parsing
+		break;
+	    case 3: default: // NOP
+		break;
+	};
+    };
+    *r=0;
+    if (counter < MAX_PARAM_NUM) PutParam(paramsPtr, StringCopy(param));
+    
+    return paramsPtr;
+};
+
+/*
+*----------------------------------------------------------------------
+*
+* FCGX_PrepareRequestVars --
+*
+*     Prepare form data variables from HTTP GET & POST.
+*
+*     Returns 0 upon success.
+*----------------------------------------------------------------------
+*/
+
+int FCGX_PrepareRequestVars(FCGX_Request *request) {
+    const char *request_method = FCGX_GetParam("REQUEST_METHOD", request->envp);
+    const char *query_string = FCGX_GetParam("QUERY_STRING", request->envp);
+    const char *content_length = FCGX_GetParam("HTTP_CONTENT_LENGTH", request->envp);
+    const char *content_type =  FCGX_GetParam("CONTENT_TYPE", request->envp);
+    char *buffer = NULL;
+
+    long content_length_i = 0;
+    long readed = 0;
+
+    if (content_length) content_length_i = atol(content_length);
+
+    if (query_string && strlen(query_string) > 0) {
+	buffer = StringCopy(query_string);
+	if (buffer) {
+	    request->getParamsPtr = GenerateParamFromWebEscapedString(buffer);
+	    free(buffer); buffer = NULL;
+	    if (request->getParamsPtr) request->getp = request->getParamsPtr->vec;
+	};
+    };
+
+    if( !strcmp(request_method, "POST")
+	&& content_length_i > 0
+	&& !strcmp(content_type, "application/x-www-form-urlencoded")
+    ) {
+	buffer = Malloc(content_length_i + 1);
+	if (buffer) {
+	    while (readed < content_length_i) {
+	    	readed += FCGX_GetStr(buffer + readed, 10000, request->in);
+	    };
+	    *(buffer + content_length_i) = 0;
+    	    request->postParamsPtr = GenerateParamFromWebEscapedString(buffer);
+	    free(buffer); buffer = NULL;
+	    if (request->postParamsPtr) request->postp = request->postParamsPtr->vec;
+	} else {
+	    return ENOMEM;
+    	};
+    };
+
+    return 0;
+};
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.