【fcgi如何处理http post上传文件】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

最近在开发一个项目,使用比较老的技术fastcgi作为web后端的处理客户端提交的GET,POST等请求。因为之前曾经使用fcgi,开发进行比较顺利,但在处理客户端POST 上传文件时就不知怎么弄了,之前没有处理过。网上查了一些fcgi处理接收文件的范例,一直没有查到。最后不得不阅读了fcgi与cgicc这两个库的源码,终于搞定了。现总结一下使用fcgi对POST 上传文件的处理。

使用fastcgi技术开发使用到两个库,分别是fcgi与cgicc。


一、fcgi是什么?

fcgi是c语言现实FastCGI开发的一个工具库,非常精小与高效,使用简单。我使用的是fcgi-2.4.1版本。
fcgi主要是对http请求接收与响应的发送,每个http请求,都产生一个FCGX_Request结构体,后续的处理与响应都是以这个FCGX_Request结构为上下文进行处理。

二、cgicc是什么?

cgicc是c++语言写的一个库,在fcgi的基础上再次封装,同样是精小与高效,提供更友好的接口给用户,重点在http的各种header 与body的解析与封装,使得对http请求的处理更加简单。本人使用的cgicc版本是cgicc-3.2.16 。

三、使用

对接收文件的处理,cgicc库已经对接收的文件数据进行解析并保存在内存里,我们只需调用接口获取即可,参考如下示例。
一个简单的多程序的fastcgi程序如下:
代码如下(示例):

#define CGI_THREAD_NUM = 4
int cgi_sock = -1;

//处理http请求的函数
void cgi_service(FCGX_Request *request) 
{
	//使用cgicc对FCGX_Request再次封装
	//后续使用io与cgi处理请求。
	cgicc::FCgiIO io(*request);
	cgicc::Cgicc cgi(&io);

	std::string method = cgi.getEnvironment().getRequestMethod();
	std::string path = cgi.getEnvironment().getScriptName();
	//对POST上传文件的处理
	if(method == "POST" && path == "/api/uploadFile"){
		cgicc::file_iterator fileIter = cgi.getFile("file");
		if(fileIter == cgi.getFiles().end()){
			printf("get none file!!!\n");
		}
		std::ofstream ofs (fileIter->getFilename());
		fileIter->writeToStream(ofs);
		ofs.close();
	}else if(method == "POST" && path == "/api/postForm"){
		//其他POST表单的处理
		std::string postData = cgi.getEnvironment().getPostData();

		//以下是继续业务的处理...
		
	}else if(methid == "GET" && path == "/api/getQuery"){
		//其他GET查询的处理
		int i;
		std::map<std::string, std::string> value_map
		for(cgicc::const_form_iterator i = cgi.getElements().begin();
			i != rcb->cgi->getElements().end(); ++i) {
			std::string name;
			std::string value;
			name = i->getName();
			value = i->getValue();
			value_map[name] = value;
			
		}
	}else{
		
	}

}
//线程函数,等待-处理不断循环
void *thread_cgi(void *param)
{
	int ret;
	FCGX_Request cgi_request;
	while(1){
		memset(&cgi_request, 0, sizeof(cgi_request));
	 	FCGX_InitRequest(&cgi_request, cgi_sock, 0);
	 	ret = FCGX_Accept_r(&cgi_request);
		if(ret == 0){
			cgi_service(&cgi_request);	//处理cgi request的请求。
			FCGX_Finish_r(&cgi_request);
		 }else{
	      		 printf("CGI accept fail\n");
		 }
	}
}

int main(int argc, char* argv[])
{
	int i;
	pthread_t id[CGI_THREAD_NUM];
	
	FCGX_Init();
	cgi_sock = FCGX_OpenSocket(":8095", 512);
	if(cgi_sock < 0)	{
		printf("open FCGX socket failed\n");
		return -1;
	}
	
	for(i = 0; i < CGI_THREAD_NUM; i++) {
	 	pthread_create(&pthread_t [i], NULL, thread_cgi, (void*)i);
	}
	return 0;
}

总结

fastcgi是比较古老的web后端技术,虽然应用开发的已经不再用该技术,但对于一些c/c++底层开发人员还是喜欢用。fcgi与cgicc配合使用,可以完成绝大部分的工作。对于https的处理,我们一般是在web服务组件前加nginx反向代理即可。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老坛程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值