/****************************************************************
filename: http_server.c
author: xxxx
function: Main file of http server
Impliment the response of Get and Post mehtods history:
created by xxxx date: 2014.01.03 *****************************************************************/ #include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <strings.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h> #include "mime.h"
#include "http_common.h"
#include "http_webapp.h"
// __DEBUG__ is debug tag #define BACK_LOG 50
#define SOCKLEN sizeof(struct sockaddr_in) //
static int open_socket(struct sockaddr_in*);
static int accept_client(int sockfd, struct sockaddr_in* paddr);
static void wait_child(); static void write_response_body(int connfd, char* uri, int filesize);
void process_request(int connfd); int main()
{
// char type[MAX_FILE_TYPE_LEN]="";
// get_mime_type("test.html",type); int sockfd = ;
int connfd = ;
struct sockaddr_in sockaddress;
pid_t chld = ;
//struct sigaction sa; bzero(&sockaddress, sizeof(struct sockaddr_in));
signal(SIGCHLD, wait_child);
//open sock
if((sockfd=open_socket(&sockaddress)) == -)
{
perror("open socket failed");
return -;
} //accept client connection
while()
{
connfd = accept_client(sockfd, &sockaddress); #if __DEBUG__
printf("client accept [%d]\n ", connfd);
#endif if((chld = fork()) > )
{ //root
close(connfd);
continue;
}else if(chld == )
{ //childi
process_request(connfd);
close(sockfd);
exit();
} } return ;
} /*--------------------------------------------------------------- functionname: open_socket
param: NA
return: return sockfd on success, -1 on fail
author: xxxx ----------------------------------------------------------------*/
static int open_socket(struct sockaddr_in* paddr)
{
int sockfd = ;
struct sockaddr_in sockaddress; bzero(&sockaddress, sizeof(sockaddress)); if((sockfd = socket(AF_INET, SOCK_STREAM, )) == -)
return -; sockaddress.sin_family = AF_INET;
sockaddress.sin_port = htons(HTTP_PORT); inet_pton(AF_INET, "10.174.8.163", &(sockaddress.sin_addr)); if(bind(sockfd, (struct sockaddr*)(&sockaddress), sizeof(sockaddress)) == -)
return -; if(listen(sockfd, BACK_LOG) == -)
return -; *paddr = sockaddress;
return sockfd;
} /*--------------------------------------------------------------- functionname: accept_client
param: NA
return: return connfd on success, -1 on fail
author: xxxx ----------------------------------------------------------------*/ static int accept_client(int sockfd, struct sockaddr_in* paddr)
{
socklen_t len = SOCKLEN;
int connfd = ; if(paddr != NULL)
{
connfd = accept(sockfd, (struct sockaddr*)(paddr), &len);
}else
{
connfd = -;
}
return connfd;
} /*---------------------------------------------------------------- functionname: wait_child_exit
param: NA
return: NA
author: xxxx TO KILL CHILD PROCESS, avoid ZOOBIE -----------------------------------------------------------------*/ static void wait_child()
{
int status = ;
while(waitpid(-, &status, WNOHANG) > )
{
#if 0
printf("child process exit\n");
#endif
}
return;
} /*----------------------------------------------------------------- functionname: process_request
param: NA
return: NA
author: xxxx http request process
history:
create by xxxx, 2014.1.08, add simple abilities -----------------------------------------------------------------*/ void process_request(int connfd)
{
char request[MAX_REQUEST_LEN];
STR_REQUEST strreq;
EN_MIME_TYPE type = MIME_ELSE;
EN_REP_STATUS status = HTTP_END;
STR_RESP response;
long filesize = ;
FILE* fstream = NULL; bzero(&strreq, sizeof(STR_REQUEST));
bzero(request, sizeof(request));
bzero(&response, sizeof(STR_RESP)); if(recv(connfd, request, sizeof(request), ) >)
{ if(parse_request(request, &strreq) ==)
{
#if __DEBUG__
printf("request:%s\n", request);
#endif get_mime_type(strreq.URI,&type); // file does not exist 404
if(file_exist(strreq.URI) == -)
{
status = HTTP_NOT_FOUND;
fstream = fopen(HTML_404, "rb");
}else
{
status = HTTP_OK;
fstream = fopen(strreq.URI, "rb");
} filesize=get_file_size(fstream);
#if __DEBUG__
printf("request file size = [%ld]\n", filesize);
#endif
//response.data = (void*)malloc(filesize);
//bzero(response.data, filesize);
get_response_head(status,type,response.head,(int)filesize);
#if __DEBUG__
printf("response head = [%s]", response.head);
#endif
//if(get_response_body(type, response.data, strreq.URI, filesize) == -1)
// perror("fill response body failed"); #if __DEBUG__
//printf("response body = [%s]\n", (char*)(response.data));
#endif
fclose(fstream);
send(connfd, response.head, strlen(response.head), );
write_response_body(connfd, strreq.URI, (int)filesize);
shutdown(connfd, SHUT_RD);
close(connfd);
}
}
} static void write_response_body(int connfd, char* uri, int filesize)
{
int fd =;
void* bodybuf = NULL;
fd = open(uri, O_RDONLY, );
bodybuf = mmap(NULL, filesize, PROT_READ, MAP_PRIVATE, fd, );
send(connfd, bodybuf, filesize, );
munmap(bodybuf, filesize);
}

http server v0.1_http_server.c的更多相关文章

  1. http server v0.1_http_reponse.c

    #include <string.h> #include <sys/stat.h> #include <sys/mman.h> #include <fcntl ...

  2. http server v0.1_http_parse.c

    #include <stdio.h> #include <string.h> #include <stdlib.h> #include "mime.h&q ...

  3. http server v0.1_http_webapp.c

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h&g ...

  4. http server v0.1_mime.c

    #include <string.h> #include "mime.h" static STR_MIME_MAP mime_map[]= { MIME_MAP(MIM ...

  5. 用FileZilla Server开FTP

    FileZilla(教程)是经典的开源FTP解决方案,包括FileZilla客户端和FileZilla Server.其中,FileZilla Server的功能比起商业软件FTP Serv-U毫不逊 ...

  6. DNS隧道之DNS2TCP实现——dns2tcpc必须带server IP才可以,此外ssh可以穿过墙的,设置代理上网

    我自己的命令: server端: dns2tcpd -F -d 1 -f ./dns2tcpd.conf 输出: 09:08:59 : Debug options.c:97 Add resource ...

  7. docker 下 安装rancher 笔记

    sudo yum update 更新系统环境 curl -sSL https://get.docker.com/ | sh 安装最新docker版本 systemctl start docker.se ...

  8. 容器基础(七): 使用docker compose部署程序

    配置 在上一节的基础上,  增加如下的docker-compose.yml文件, 然后用docker-compose up命令启动容器进行部署: version: " services: s ...

  9. 容器基础(八): 使用docker swarm部署程序

    环境 基于上一节的env/server:v0.1, env/worker:v0.1镜像, 在基于debian8.2的两台机器上测试部署docker swarm. docker service部署 ➜ ...

随机推荐

  1. mybatis03

    .2导入jar包 从mybatis管网下载(地址:https://github.com/mybatis/mybatis-3/releases) mybatis-.pdf---操作手册 mybatis- ...

  2. redis持久化和常见故障

    https://segmentfault.com/a/1190000004135982 redis 主从复制 Redis主从复制的原理 当建立主从关系时,slave配置slaveof <mast ...

  3. cocos2d-x plist+wen使用

    http://zhan.renren.com/tag?value=cocos2dx&from=template http://blog.csdn.net/zhanglongit/article ...

  4. Linq扩展方法之All 、Any

    // Summary: // 确定序列中的所有元素是否满足条件. // Parameters: // source:包含要应用谓词的元素的 System.Collections.Generic.IEn ...

  5. Oracle 汉字在不同字符集下所占字节

    今天发现了一个问题,一个长度设置为2000字节的字段,插入一条长度为1000的汉字数据,竟然报错了. 一个汉字占两个字节,按理说刚好是2000个字节.但通过查看日志,发现插入数据的长度为3000字节. ...

  6. 30、ADO.NET、事务、DataSet

    ADO.NET ADO.NET是一组用于和数据源进行交互的面向对象类库.通常数据源是数据库,但也可以是文本文件.Excel表格.XML文件. 说白了就是使用.net操作数据库的一套类库. ADO.NE ...

  7. 自己做的demo---c语言的基本语法,过阵子可以重新写一些算法跟数据结构了

    //输入a,b,输出a+b /*#include<stdio.h> int main() { int a,b; scanf("%d%d",&a,&b); ...

  8. js--小结⑥---typeof

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. Update Statistics用法

    Update Statistics语句的作用将创建的数据库表的有关统计信息更新到系统 sysmater的相关表中,以便查询优化器选择最佳的执行路径,当sysmaster库中没有相应的统计信息,或者统计 ...

  10. NUnit + VS2010 简单入门

    一.环境准备 1. NUnit 2.6.3 下载地址:https://launchpadlibrarian.net/153448476/NUnit-2.6.3.msi 2. VS2010 二.安装 N ...