`
duoerbasilu
  • 浏览: 1481334 次
文章分类
社区版块
存档分类
最新评论

c语言开发cgi学习笔记

 
阅读更多

初学cgi,实现一个简单的网页,能够完成上传、下载、删除、浏览目录的功能。

工欲善其事必先利其器,首先要了解一下http协议,HTTPHyperTextTransferProtocol)是超文本传输协议的缩写,它用于传送WWW方式的数据,关于HTTP协议的详细内容请参考RFC2616

cgi程序往往需要分析网络包,为此介绍一利器:httpwatch,这个是ie的一个插件,只需要选择相应的网站,软件就可以对网站与IE之间的需求/回复的通讯情况进行分析并在同一界面显示其相应日志记录。每一个HTTP记录都可以详细的分析其Cookies、消息头、字符查询等信息。支持HTTPS及分析报告输出为XMLCSV等格式。对于firefox浏览器也有一个自带的插件Httpfox,功能类似。

上传:

上传需要用到httppost提交方式,其中关于postget请求方法,具体的可以在网上寻求解答,这两者的区别在于使用postform中数据在http协议的消息体中传输,而使用getform中的数据将编码到url中。可以参考rfc1867协议。

上传的主要思路是:解析出http消息体中的数据,将其写到服务器的指定目录下。

首先遇到的就是如何获取要上传的文件的文件名,通过用Httpfox分析http消息,可以发现文件名就包含在消息体中。

因此,只需要从消息体中解析出来文件名,再以这个名字写到服务器上就可以了。

在处理时,先把消息接收到缓冲区中(eg.Buf,这个buf不仅包含文件的内容,头和尾还有一些http消息相关的内容,因此需要去除这些内容),然后把提取出来的内容写到文件中。

通过

intlen=atoi(getenv("CONTENT_LENGTH"))

可以获得整个消息的长度,便于分配缓冲区。

然后

char*type=getenv("CONTENT_TYPE");

char*boundary=strstr(type,"boundary");

可以获取到消息中的boundary,便于从整个消息体中分割出文件内容。

char*buf=(char*)malloc(sizeof(char)*len);

if(!buf)

{

printf("bufmallocerror\n\n");

return0;

}

fread(buf,1,len,stdin);

读出数据到buf

char*name=strstr(buf,"filename=");找到"filename="的地方,=后面的就是文件名,提取出文件名即可,之后就是通过一系列的字符串操作去掉buf中多余的内容,然后

fwrite(buf,1,len,fp);写入到文件中。

下载:

下载使用httpget方式。

下载的主要思路是:获取输入的文件名,以只读方式打开,不成功说明不存在;成功则打开文件读取内容到stdout

char*param=getenv("QUERY_STRING");

char*name=strstr(params"name=");

可以得到文件名。

然后可以通过

fseek(fp,0L,SEEK_END);

intfile_len=ftell(fp);

获取到文件长度。

在读取内容输出到stdout之前需要打印一下内容

printf("Status:200OK\r\n");

printf("Content-Length:%d\r\n",file_len);

printf("Accept-Ranges:bytes\r\n");

printf("Content-Disposition:file;filename=\"%s\"\r\n",file_name);

printf("Content-Type:%s\r\n",file_type);

然后读取文件内容到stdout

while((len=fread(buf,1,sizeof(buf),fp))>0)

{

fwrite(buf,1,len,stdout);

}

删除:

删除获取输入文件名的方法与下载一样。

根据文件名判断输入的是一个文件名还是一个目录名

structstatstat_buf;

lstat(path,&stat_buf);

if(S_ISREG(stat_buf.st_mode))//是文件

remove(path);

列出目录文件:

默认的目录是/usr/local/apache/cgi-bin

需要用到opendirreaddir函数。

voidlist_dir(constchar*path)

{

DIR*dir;

structdirent*entry;

structstatstat_buf;

if((dir=opendir(path))==NULL)

{

printf("cannotopendir:%s\n",path);

return;

}

while((entry=readdir(dir))!=NULL)

{

lstat(entry->d_name,&stat_buf);

if(S_ISDIR(stat_buf.st_mode))

{

if(strcmp(entry->d_name,".")==0||strcmp(entry->d_name,"..")==0)

continue;

printf("%s\t\t%d<br>",entry->d_name,(int)stat_buf.st_size);

}

else

printf("%s\t\t%d<br>",entry->d_name,(int)stat_buf.st_size);

}

closedir(dir);

}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics