用c语言创建管理系统步骤,C语言构建WEB管理系统(五):CGI实现上传文件

【版权声明:尊重原创,转载请保留出处:blog.youkuaiyun.com/shallnet,文章仅供学习交流,请勿用于商业用途】

在很多网站中经常会遇到有向服务器上传文件的情况,比如在博客或空间中上传自己的头像。这一节我们来看一下在后台如何使用C语言实现文件上传这一功能。

首先创建一个html文档来上传文件,然后使用wireshark抓取数据包来分析一下上传文件的文件内容如何解析。html文档如下:

/p>

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

CGI 实现文件上传

下面为wireshark抓包获取的数据:

0818b9ca8b590ca3270a3433284dd417.png

所以要解析出文件内容需要首先从content_type中获取boundry,以下为在解析出boundry基础上将文件内容写入到一个临时文件中的处理函数:

int sln_cgi_input_multi_content_parse(const char *content_input,

int content_length, const char *boundary)

{

char attr[SLN_ATTR_MAX], value[SLN_MAX_VALUE_LEN],

filename[SLN_MAX_FILENAME_LEN], tfilename[SLN_MAX_FILENAME_LEN],

tmpname[SLN_MAX_FILENAME_LEN];

char *start, *end, *pname, *quote;

int boundary_len, attr_len, value_len, filename_len, file_size = 0;

FILE *fp = NULL;

boundary_len = strlen(boundary);

start = (char *)content_input;

if ((end = strstr(start, boundary))) {

start = end + boundary_len;

}

while (start) { // search boundary

attr[0] = '\0', filename[0] = '\0', filename[0] = '\0', tfilename[0] = '\0';

if (0 == memcmp(start, "--\r\n", 4)) { //reach the end

break;

} else {

start += 2; //strlen("\r\n") = 2;

}

/*

* betwen the start and end is a form data,

* "name" and "filename"(probably) is in it

*/

end = strstr(start, "\r\n\r\n");

if (NULL == end) {

break;

}

*end = '\0';

/* get attr name */

pname = strstr(start, "name=\"");

if (NULL == pname) {

start = end + 1;

continue;

}

quote = strchr(pname + 6, '\"'); //strlen("name=\"") = 6;

if (NULL == quote) {

start = end + 1;

continue;

}

attr_len = quote - (pname + 6);

strncpy(attr, pname + 6, attr_len);

attr[attr_len] = '\0';

printf("

attr(len=%d): %s

\n", attr_len, attr);

/* try to get filename */

pname = strstr(start, "filename=\"");

if (NULL != pname) {

quote = strchr(pname + 10, '\"'); //strlen("filename=\"") = 10;

if (NULL == quote) {

start = end + 1;

continue;

}

filename_len = quote - (pname + 10);

strncpy(filename, pname + 10, filename_len);

filename[filename_len] = '\0';

printf("

filename(len=%d): %s

\n", filename_len, filename);

}

start = end + 4; //strlen("\r\n\r\n") = 4;

if ('\0' == filename[0]) { // not file, to get value

end = strstr(start, boundary);

if (NULL != end) {

value_len = (end-4) - start; //"\r\n--"

if (value_len > sizeof(value)) {

value_len = sizeof(value) - 1;

}

strncpy(value, start, value_len);

value[value_len - 1] = '\0';

printf("

value(len=%d): %s

\n", value_len, value);

start = end + strlen(boundary);

}

} else { //is file, to get file content

end = sln_memsearch(start, content_length - (start-content_input), boundary, boundary_len);

if (NULL != end) {

file_size = (end-4) - start; //"\r\n--"

//sln_dump_mem((unsigned char *)end, 8);

// generate tmp file

if (NULL == tmpnam(tmpname)) {

snprintf(tfilename, SLN_MAX_FILENAME_LEN, "%s", filename);

} else {

snprintf(tfilename, SLN_MAX_FILENAME_LEN, "%s", tmpname);

}

// write file content to tmp file

file_size =

file_size > SLN_MAX_CONTENT_LEN ? SLN_MAX_CONTENT_LEN : file_size;

fp = fopen(tfilename, "w+");

if (NULL != fp) {

fwrite(start, 1, file_size, fp);

fclose(fp);

} else {

//SLN_CGI_ERR("fopen failed!\n", tfilename);

}

printf("

tfilename: %s, file_size: %d

\n", tfilename, file_size);

//sln_dump_mem((unsigned char *)start, file_size);

start = end + strlen(boundary);

}

}

}

return 0;

}

最后将代码编译成可执行文件upload.cgi,在页面上传两个文件,如下:

0818b9ca8b590ca3270a3433284dd417.png

提交后页面跳转到如下页面:

0818b9ca8b590ca3270a3433284dd417.png

我们将所示文件cat出来看一下文件内容,如下:

[root@shallnet 4_upload]# cat /tmp/fileke5tvT

The strings in the environment list are of the form name=value.[root@shallnet 4_upload]#

[root@shallnet 4_upload]# cat /tmp/file7dP091

This page is part of release 3.22 of the Linux man-pages project.[root@shallnet 4_upload]#

可以看到文件上传成功!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值