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;
+};