简易http服务器的实现(实现)httpserver.c

/**

介绍下开发环境

linux 2.6.x内核

redhat 5

gcc 4.4

httpserver.c

**/

/*-----------------------------------------------------------------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <errno.h>
#include "wrap.h"
#include "httpserver.h"

#define MAX_LINE 512
#define DEF_DIR "/home/tyrael"

static struct sockaddr_in host_addr;
static int hostfd;

static char err404[512] = "HTTP/1.1 404 ERROR\r\nConnectlon:close\r\n";
static char context[8192] = {0};

typedef struct request_line {
char request_type[10];
char path[512];
char http_version[10];
} request_line_t;

char* _strstrip(char* str) {
int len = strlen(str);
if (!len)
return str;
char* tmp = str + len -1;
while (isspace(*tmp)) {
*tmp = 0;
tmp--;
}

while (isspace(*str)) {
*str = 0;
str++;
}

return str;
}

void read_requestline(const char* src,struct request_line *req_line) {
char* point = NULL;
char* spc = NULL;
char* start = NULL;
char* end = NULL;
if (src && req_line) {
if ((start = spc = strchr(src,' '))) {
strncpy(req_line->request_type,src,spc - src);
req_line->request_type[spc - src] = 0;
}
if ((end = spc = strrchr(src,' '))) {
strncpy(req_line->http_version,spc + 1,src + strlen(src) - spc);
}
if (start && end) {
strncpy(req_line->path,start + 1,end - start);
req_line->path[end - start] = 0;
}

} else
return ;
}


int start_http(const char* ip, int port) {
int clientfd,clientlen,status;
struct sockaddr_in clientaddr;
char buf[MAX_LINE * 100] = {0};
if (!ip)
err_exit("IP MUST DON'T NULL");
if (port <=0 || port >65535)
err_exit("PORT MUST >0 AND <= 65535");
Set_addr_port(&host_addr,NULL,port);

hostfd = Socket(AF_INET,SOCK_STREAM,0);

int f = 1;
setsockopt(hostfd,SOL_SOCKET,SO_REUSEADDR,&f,sizeof(f));

Bind(hostfd,(struct sockaddr *)&host_addr,sizeof(host_addr));

Listen(hostfd,20);

char* point = NULL;

char* tmp_store = buf;

char request_line[MAX_LINE] = {0};

while (1) {
clientlen = sizeof(clientaddr);
clientfd = Accept(hostfd,(struct sockaddr *)&clientaddr,&clientlen);
printf("%s\n",inet_ntoa(clientaddr.sin_addr));

//status = Readline(clientfd,buf,MAX_LINE);
while (1) {
status = Read(clientfd,tmp_store,512);
if (status == -1)
break;
printf("%s",buf);
if (status < 512)
break;
tmp_store += status;
*tmp_store = 0;
}
if (strlen(buf) > 0) {
point = strstr(buf,"\r\n");
if (point) {
strncpy(request_line,buf,point - buf);
request_line[point-buf] = 0;
struct request_line rl;
memset(&rl,0,sizeof(request_line));
read_requestline(request_line,&rl);
printf("#%s\n",rl.request_type);
if (!strncmp(rl.request_type,"GET",3) ||!strncmp(rl.request_type,"POST",4) || !strncmp(rl.request_type,"HEAD",4)) {
if (strlen(rl.path)) {

char* _c = strrchr(rl.path,'.');
int len = strlen(rl.path);
if (_c) {
if (!strncasecmp(_c + 1,"jpg",3)) {
strcpy(context,"HTTP/1.1 200 OK\r\nContext-Type: image/jpg\r\n\r\n");
printf("#jpg\n");
} else {
strcpy(context,"HTTP/1.1 200 OK\r\nContext-Type: text/html\r\n\r\n");
printf("#html\n");
}
} else {
strcpy(context,"HTTP/1.1 200 OK\r\nContext-Type: text/html\r\n\r\n");
printf("#other\n");
}

int filefd;
char fileaddr[256] = {0};
strcpy(fileaddr,DEF_DIR);
strcat(fileaddr,_strstrip(rl.path));
filefd = open(fileaddr,O_RDONLY);
printf("#%s#\n",fileaddr);
if (filefd == -1) {
perror("err");
printf("#%s\n",fileaddr);
memset(fileaddr,0,strlen(fileaddr));
strcpy(fileaddr,DEF_DIR);
strcat(fileaddr,"/err.html");
filefd = open(fileaddr,O_RDONLY);
memset(context,0,8192);
strcpy(context,"HTTP/1.1 404 Not Found\r\nContent-Type: text/html\r\n\r\n<html><body>request file not found</body></html>");
Write(clientfd,context,strlen(context));
} else {

char test[512] = {0};
int co = 0;
char* cont = context;
int count_img = 0;
while (1) {
co = read(filefd,test,512);
count_img += co;
if (co <=0) {
if (co == -1)
perror("error:");
break;
}
//strcat(context,test);
memcpy(cont,test,512);
cont += 512;
memset(test,0,512);
}
int c = Write(clientfd,context,count_img);
printf("%d\n",c);
}

} else {
int c = Write(clientfd,err404,strlen(err404));
printf("%d\n",c);
}
}
close(clientfd);
printf("#%s$\n",rl.path);
printf("#%s\n",rl.http_version);
}
}

}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值