//==========================================================
//文件名称:senddata.c
//功能描述:实现客服端信息的预处理,与数据发送
//包含文件:senddata.h
//维护日期:
//===========================================================
#include "senddata.h"
char request_file[100];
//===================================================================================
//函数名称:get_client_request(int connfd,char *request)
//功能描述:读取client段的请求报文,并获得报文的第一行
//函数参数:connfd 接收到的client端的socket文件描述符,request 保存报文第一行的指针变量
//返回值: 无
//=====================================================================================
void get_client_request(int connfd,char *request)
{
char recvbuf[4096];
char *pos;
memset(recvbuf,0,sizeof(recvbuf));
if(read(connfd,recvbuf,sizeof(recvbuf))<=0)
{
exit(0);
}
if((pos=strstr(recvbuf,"\n"))!=NULL)
{
*pos='\0';
}
strcpy(request,recvbuf);
}
//============================================================================
//函数名称:file_is_found
//功能描述:查找当前目录下,文件是否为请求文件,此函数为ftw函数服务的被动型函数
//函数参数:cur_path ftw函数存放当前路径的指针变量,file_stat ftw存放文件信息的
// 文件状态结构体指针,falg ftw存放文件类型的整形变量
//返回值: int找到文件返回1,没找到返回0
//===========================================================================
int file_is_found(char *cur_path,struct stat *file_stat,int flag)
{
if(flag==FTW_F)
{
if(strcmp( cur_path+(strlen(cur_path)-strlen(request_file)),request_file)==0 )
{
//printf("in 20 file=%s\n",cur_path);
strcpy(request_file,cur_path);
return 1;
}
}
return 0;
}
//===================================================================
//函数名称:serv_resource_find
//功能描述:遍历server当前路径下的所有目录,寻找client请求的资源文件,
// 并将文件大小保存到指针变量file_size中
//函数参数:serv_resource_path资源搜索路径指针,保存文件大小的指针变量
//返回值: int,找到请求文件返回1,没找到返回0;
//======================================================================
int serv_resource_find(char *serv_resource_path,off_t *file_size)
{
int ret=0;
struct stat file_stat;
ret=ftw(serv_resource_path,(int (*)())file_is_found,2);//遍历目录树,参考unix函数手册
if(ret==1)
{
*file_size=file_stat.st_size;
return 1;
}
else
{
return 0;
}
}
//====================================================================================
//函数名称:send_data
//功能描述:根据client_info的内容分析报文格式,并发送数据
//函数参数:connfd 已连接到的客服端socket文件描述符,client_info报文第一行内容指针变量
//返回值: 无
//====================================================================================
void send_data(int connfd,char *client_info)
{
char *resp_head = "HTTP/1.1 200 OK\r\n" \
"Content-Type: text/html\r\n" \
"Content-Length:%ld\r\n" \
"\r\n";
char *not_found = "HTTP/1.1 404 Not Found\r\n" \
"Content-Type: text/html\r\n" \
"Content-Length: 40\r\n" \
"\r\n" \
"<HTML><BODY>File not found</BODY></HTML>";
char *bad_request = "HTTP/1.1 400 Bad Request\r\n" \
"Content-Type: text/html\r\n" \
"Content-Length: 39\r\n" \
"\r\n" \
"<h1>Bad Request (Invalid Hostname)</h1>";
char *moved_permanently =
"HTTP/1.1 301 Moved Permanently\r\n"\
"Content-Length: 147\r\n" \
"Content-Type: text/html\r\n" \
"Location: %s\r\n" \
"\r\n" \
"<head><title>Document Moved</title></head><body><h1>Object Moved</h1>This document may be found <a HREF=\"%s\">here</a></body>";
char *cli_info_arg[5];
char temp[30];
char buf[2048];
char respbuf[1024];
int cli_fd;
unsigned long int file_lenth=0;
memset(temp,0,sizeof(temp));
memset(request_file,0,sizeof(request_file));
splitinfo(client_info," ",cli_info_arg);//分割信息得到客户端要访问的文件名
strcpy(request_file,cli_info_arg[1]);
strcpy(temp,cli_info_arg[1]);
temp[0]='\0';
if(!strcmp(request_file,"/"))
{
strcpy(request_file,"index.htm");
}
else //去掉文件前的"/"
{
strcpy(request_file,temp+1);
}
//==========判断当前路径是否有client要访问的文件
//if(access(cli_file,F_OK)==0)
off_t file_size;
//if(serv_resource_find(cli_file,&file_size))
if(serv_resource_find("./",&file_size))
{
//char *fp=cli_file;
//struct stat request_file;
//stat(fp,&request_file);
//-------发送应答报头
//sprintf(respbuf,resp_head,request_file.st_size);
sprintf(respbuf,resp_head,file_size);
write(connfd,respbuf,strlen(respbuf));
//-------用fprintf类的函数式,因为f*类函数是带有缓冲,所以必须用fflush才能使数据从缓冲区输出。
//FILE *newfp = fdopen(connfd, "w");//相当于把整数文件描述符,转换为文件指针
//fprintf(newfp, resp_head, len);
//fflush(newfp);
memset(buf,0,sizeof(buf));
if((cli_fd=open(request_file,O_RDONLY))<0)
{
perror("can not open file in send_data()\n");
exit(0);
}
int len;
while((len = read(cli_fd,buf,sizeof(buf)))>0)
{
//printf("%s",buf);
write(connfd,buf,len);
memset(buf,0,sizeof(buf));
}
close(cli_fd);
}
else
{
printf("in is not!\n");
write(connfd,not_found,strlen(not_found));
}
}
|