如何使用c语言解析httppost请求

头文件

#ifndef _UPLOAD
#define _UPLOAD

#include "fastcgi/fcgiapp.h"

//#include "sysinc.h"
#ifdef _WIN32
/*! \def GRCALL
*  the calling convention of functions exported by modules.
*/
#	define GRCALL __stdcall
#	define GRINLINE __inline
#else
#	define GRINLINE inline

/*! \def GRCALL
*  the calling convention of functions exported by modules.
*/
#	if defined(__CYGWIN__)
#		define GRCALL __stdcall
#	else
#		define __stdcall
#		define GRCALL
#	endif
#endif


#define EUPLOAD_SUCCESS 0 
#define EUPLOAD_NO_DATA -1
#define EUPLOAD_READ    -2
#define EUPLOAD_WRITE   -3


#ifdef __cpluscplus
extern "C" {
#endif

int GRCALL upload_file_save_as(FCGX_Stream* in,FCGX_Stream* out, FCGX_ParamArray envp,const char *save_path,char(* filePath)[260]);

int GRCALL upload_file_save_as(const char *save_path);

#ifdef __cpluscplus
}
#endif


#endif


cpp

#include "stdafx.h"
#include "fastcgi/upload.h"
//#include "logger.h"
#include "fastcgi/fcgi_stdio.h"
#include "string.h"
#include <stdlib.h>
#include <windows.h>

#define DEAL_BUF_LEN 1024
#define SIGN_CODE_LEN 100
#define FILE_NAME_LEN 64

enum
{
    STATE_START,
    STATE_GET_SIGN_CODE,
    STATE_GET_FILE_NAME,
    STATE_GET_FILE_START,
    STATE_GET_FILE_CONTENT,
    STATE_CHECK_END,
    STATE_END
};


int GRCALL upload_file_save_as(FCGX_Stream* in, FCGX_Stream* out, FCGX_ParamArray envp, const char *saveas,char(* saveName)[260])
{
	FILE *fp=NULL;
	int getState = STATE_START;
		// uploaded file content length 
	int contentLength;
	int nowReadLen;
	int signCodeLen;
	int tmpLen;
	char *nowReadP;
	char *nowWriteP = NULL;
	char dealBuf[DEAL_BUF_LEN];
	// http boundary 
	char signCode[SIGN_CODE_LEN];
	char tmpSignCode[SIGN_CODE_LEN];
	char fileName[FILE_NAME_LEN];
	memset(dealBuf, '0', DEAL_BUF_LEN);
	memset(signCode, '0', SIGN_CODE_LEN);
	memset(fileName, '0', FILE_NAME_LEN);
	nowReadLen = 0;
	int fileNum = 0;

	//SYSTEMTIME sys;
	//GetLocalTime(&sys);
	//FCGX_FPrintF(out, " before 1:  %02d:%02d.%03d 星期%1d ",  sys.wMinute, sys.wSecond, sys.wMilliseconds, sys.wDayOfWeek);


	if ((char *)FCGX_GetParam("CONTENT_LENGTH", envp) != NULL)
	{
		contentLength = atoi((char *)FCGX_GetParam("CONTENT_LENGTH", envp));
		FCGX_FPrintF(out, "CONTENT_LENGTH %d \n", contentLength);
	}
	else
	{
		FCGX_FPrintF(out, "EUPLOAD_NO_DATA\n");
		return EUPLOAD_NO_DATA;
	}

	while (contentLength > 0)
	{
		if (contentLength >= DEAL_BUF_LEN)
		{
			nowReadLen = DEAL_BUF_LEN;
		}
		else
		{
			nowReadLen = contentLength;
		}
		contentLength -= nowReadLen;
		//if (FCGI_fread(dealBuf, sizeof(char), nowReadLen, FCGI_stdin) != (size_t)nowReadLen)
		if (FCGX_GetStr(dealBuf, nowReadLen, in) != (size_t)nowReadLen)
		{
			//log_error("read error %d", nowReadLen);
			FCGX_FPrintF(out, "read error %d \n", nowReadLen);
			FCGX_FPrintF(out, "actual read %d \n", fread(dealBuf, sizeof(char), nowReadLen, FCGI_stdin));
			return EUPLOAD_READ;
		}
		nowReadP = dealBuf;
		//FCGX_FPrintF(out, "content is %s \n", dealBuf);
		/*while (nowReadLen > 0)
		{
			FCGX_FPrintF(out, "%c \n", *nowReadP);
			nowReadP++;
			nowReadLen--;
		}*/
		while  (nowReadLen > 0)
		{
			switch (getState)
			{
			case STATE_START:
				nowWriteP = signCode;
				getState = STATE_GET_SIGN_CODE;
			case STATE_GET_SIGN_CODE:
				if (strncmp(nowReadP, "\r\n", 2) == 0)
				{
					//FCGX_FPrintF(out, "## signCode is %s", signCode);
					signCodeLen = nowWriteP - signCode;
					//FCGX_FPrintF(out, "## signCode LENGTH is %d", signCodeLen);
					nowReadP++;
					nowReadLen--;
					*nowWriteP = 0;
					getState = STATE_GET_FILE_NAME;
					
				}
				else
				{
					*nowWriteP = *nowReadP;
					nowWriteP++;
				}
				break;
			case STATE_GET_FILE_NAME:
				if (strncmp(nowReadP, "filename=", strlen("filename=")) == 0)
				{
					nowReadP += strlen("filename=");
					nowReadLen -= strlen("filename=");
					nowWriteP = fileName + strlen(saveas);
					memset(fileName, '0', FILE_NAME_LEN);
					while (*nowReadP != '\r')
					{
						if (*nowReadP == '\\' || *nowReadP == '/')
						{
							nowWriteP = fileName + strlen(saveas);
						}
						else if (*nowReadP != '\"')
						{
							*nowWriteP = *nowReadP;
							nowWriteP++;
						}
						nowReadP++;
						nowReadLen--;
						if (nowReadLen <= 0)
							break;
					}
					*nowWriteP = 0;
					nowReadP++;
					nowReadLen--;
					getState = STATE_GET_FILE_START;
					memcpy(fileName, saveas, strlen(saveas));
					//
					if (fileNum > 1)
						fileNum = 1;
					sprintf(saveName[fileNum], "%s",fileName);
					//FCGX_FPrintF(out, "open file %s ", fileName);
					if ((fp = fopen(fileName, "wb")) == NULL)
					{
						//log_error("open file %s error %d", fileName, errno);
						
						FCGX_FPrintF(out, "open file %s error %d", fileName, errno);
						return EUPLOAD_WRITE;
					}
					else
					{
						fileNum++;
					}
				}
				break;
			case STATE_GET_FILE_START:
				if (strncmp(nowReadP, "\r\n\r\n", 4) == 0)
				{
					nowReadP += 3;
					nowReadLen -= 3;
					getState = STATE_GET_FILE_CONTENT;
				}
				break;
			case STATE_GET_FILE_CONTENT:
				if (*nowReadP != '\r')
				{
					//fputc(*nowReadP, fp);
					fwrite(nowReadP, sizeof(char), 1, fp);
				}
				else
				{
					
					if (nowReadLen >= (signCodeLen + 2)) //\r\n=2
					{

						if (strncmp(nowReadP + 2, signCode, signCodeLen) == 0)
						{
							
							//FCGX_FPrintF(out, "STATE_GET_FILE_CONTENT and end:%d ,signCodeLen is %d ", nowReadLen, signCodeLen);
							
							//FCGX_FPrintF(out, "nowReadp: %c  ", *(nowReadP + 2 + signCodeLen));
							//FCGX_FPrintF(out, "nowReadp: %c  ", *(nowReadP + 2 + signCodeLen+1));
							//FCGX_FPrintF(out, "nowReadp: %c  ", *(nowReadP + 2 + signCodeLen+2));
	
							//getState = STATE_END;
							//nowReadLen = 1;
							
							
							if (nowReadLen >= (signCodeLen + 4) && strncmp(nowReadP + 2 + signCodeLen, "--", 2) == 0)//真正的结尾
							{
								//FCGX_FPrintF(out, "## end ##  ");
								getState = STATE_END;
								nowReadLen = 1;
							}
							//else if(nowReadLen<(signCodeLen + 4) )//刚好到boundary后面的-未读到时,break
							//{
							//	break;
							//}
							
							else
							{
								//FCGX_FPrintF(out, "try to close file and start another file");
								if (fp != NULL)
								{
									FCGX_FPrintF(out, "close file and start another file");
									fclose(fp);
									fp = NULL;
								}
								

								getState = STATE_GET_FILE_NAME;
								//getState = STATE_START;
								//memset(signCode, 0, SIGN_CODE_LEN);

								//FCGX_FPrintF(out, "nowReadp ==r## and goto START");
							}
								
							//getState = STATE_END;
							//nowReadLen = 1;
						}
						else
						{
							//fputc(*nowReadP, fp);
							fwrite(nowReadP, sizeof(char), 1, fp);
							//FCGX_FPrintF(out, "%s", nowReadP);
						}
					}
					else
					{
						getState = STATE_CHECK_END;
						nowWriteP = tmpSignCode;
						*nowWriteP = *nowReadP;
						nowWriteP++;
						tmpLen = 1;


						//FCGX_FPrintF(out, "check end nowRadp ==r##");
					}
				}
				break;
			case STATE_CHECK_END:
				if (*nowReadP != '\r')
				{
					if (tmpLen < signCodeLen + 2)
					{
						*nowWriteP = *nowReadP;
						nowWriteP++;
						tmpLen++;
						if (tmpLen == signCodeLen + 2)
						{
							*nowWriteP = 0;
							//FCGX_FPrintF(out, "tmpSignCode is %s \n", tmpSignCode);
							if ((tmpSignCode[1] == '\n') && (strncmp(tmpSignCode + 2, signCode, signCodeLen) == 0))
							{
								
								/*FCGX_FPrintF(out, "nowReadp: %c  ", *nowReadP);
								nowReadP++;
								FCGX_FPrintF(out, "nowReadp: %02x  ", *nowReadP);
								nowReadP++;
								FCGX_FPrintF(out, "nowReadp: %02x  ", *nowReadP);
								nowReadP++;
								FCGX_FPrintF(out, "nowReadp: %c  ", *nowReadP);
								nowReadP++;
								FCGX_FPrintF(out, "nowReadp: %c  ", *nowReadP);
								nowReadP++;
								FCGX_FPrintF(out, "nowReadp: %c  ", *nowReadP);
								    getState = STATE_END;
									nowReadLen = 1;
								*/
								/*
								FCGX_FPrintF(out, "nowReadp: %c  ", *nowReadP);
								nowReadP++;
								FCGX_FPrintF(out, "nowReadp: %02x  ", *nowReadP);
								nowReadP++;
								FCGX_FPrintF(out, "nowReadp: %02x  ", *nowReadP);
								nowReadP++;
								FCGX_FPrintF(out, "nowReadp: %c  ", *nowReadP);
								nowReadP -=3;
								*/
								
									
								nowReadP++;
								nowReadLen--;
								//if (nowReadLen >= (signCodeLen + 4) && strncmp(nowReadP + 2 + signCodeLen, "--", 2) == 0)//真正的结尾
								if (nowReadLen >= 2 && strncmp(nowReadP, "--", 2) == 0)
								{
									//FCGX_FPrintF(out, "nowReadp ==r## and goto END");
									//FCGX_FPrintF(out, "### check end,signCodeLen: %d,nowReadLen:%d", signCodeLen, nowReadLen);
									getState = STATE_END;
									nowReadLen = 1;
									
								}
								//else if(nowReadLen<2)//刚好到boundary后面的--未读到时,break
								//{
								//	break;
								//}
								else
								{
									if (fp != NULL)
									{
										try {
											FCGX_FPrintF(out, "close file checkend");
											fclose(fp);
										}
										catch (...) {
										}
									}
									getState = STATE_GET_FILE_NAME;
									
									//getState = STATE_START;
									//memset(signCode, 0, SIGN_CODE_LEN);

									//FCGX_FPrintF(out, "nowReadp ==r## and goto START");
								}
								
								//getState = STATE_END;
								//nowReadLen = 1;
							}
							else
							{
								//fprintf(fp,tmpSignCode);
								fwrite(tmpSignCode, sizeof(char), tmpLen, fp);
								getState = STATE_GET_FILE_CONTENT;
								//FCGX_FPrintF(out, "check end and get fileContent,tempSignCode: %s", tmpSignCode);
								//FCGX_FPrintF(out, "checkend and not end \n");
							}
						}
					}
				}
				else
				{
					*nowWriteP = 0;
					//fprintf(fp,tmpSignCode);
					fwrite(tmpSignCode, sizeof(char), tmpLen, fp);
					nowWriteP = tmpSignCode;
					*nowWriteP = *nowReadP;
					nowWriteP++;
					tmpLen = 1;
					FCGX_FPrintF(out, "checkend and nowReadP == r \n");
				}
				break;
			case STATE_END:
				nowReadLen = 1;
				//FCGX_FPrintF(out, "state  end \n");
				break;
			default:break;
			}
			if (getState != STATE_START)
			{
				nowReadLen--;
				nowReadP++;
			}
			else
			{
				nowReadLen-=2;
				nowReadP+=2;
			}
			
		}
	}


	//add for two picture by luodaliang
	if (fp != NULL)
	{
		FCGX_FPrintF(out, "close file end");
		fclose(fp);	
	}

	//GetLocalTime(&sys);
	//FCGX_FPrintF(out, " before 5:  %02d:%02d.%03d 星期%1d ", sys.wMinute, sys.wSecond, sys.wMilliseconds, sys.wDayOfWeek);

	return EUPLOAD_SUCCESS;
}


  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值