Chinaunix首页 | 论坛 | 博客
  • 博客访问: 375830
  • 博文数量: 62
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 557
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-01 14:04
文章分类

全部博文(62)

文章存档

2014年(1)

2013年(61)

分类: C/C++

2013-11-17 19:35:49

原文地址:实现一个简单的web服务器 作者:1jjk

/*****************************************************
name: function b.o
written by:1jjk
E-mail:lingjiujianke@gmail.com
compile: gcc -c b.c
******************************************************/

#include<netinet/in.h>
#include<netdb.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<stdio.h>
#include<unistd.h>
#include<strings.h>
#include<time.h>


#define BACKLOG    1

int make_server_socket_q(int, int);

int make_server_socket(int portnum)
{
    return make_server_socket_q(portnum,BACKLOG);
}

int make_server_socket_q(int portnum, int backlog)
{
    struct sockaddr_in saddr;
    int sock_id;

    sock_id=socket(PF_INET, SOCK_STREAM, 0);

    if(sock_id==-1)
    {
        return -1;
    }
    bzero((void *)&saddr,sizeof(saddr));
    saddr.sin_addr.s_addr=htonl(INADDR_ANY);
    saddr.sin_port=htons(portnum);
    saddr.sin_family=AF_INET;
/*bind*/
    if(bind(sock_id,(struct sockaddr *)&saddr,sizeof(saddr))!=0)
        return -1;
/*listen*/
    if(listen(sock_id,backlog)!=0)
        return -1;
    return sock_id;
}

int connect_to_server(int portnum, int backlog)
{
    struct sockaddr_in saddr;
    int sock_id;
/*net set*/
    sock_id=socket(PF_INET, SOCK_STREAM, 0);

    if(sock_id==-1)
    {
        return -1;
    }


    bzero((void *)&saddr,sizeof(saddr));
    saddr.sin_addr.s_addr=htonl(INADDR_ANY);
    saddr.sin_port=htons(portnum);
    saddr.sin_family=AF_INET;
/*connect*/
    if(connect(sock_id,(struct sockaddr *)&saddr,sizeof(saddr))!=0)
        return -1;
    return sock_id;
}

 

 

/*****************************************************
name: simple web
written by:1jjk
E-mail:lingjiujianke@gmail.com
compile: gcc -O2 -Wall -o web web.c b.o
******************************************************/

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<strings.h>
#include<sys/utsname.h>

int main(int ac,char *av[])
{
    int sock,fd;
    FILE *fpin;
    char request[BUFSIZ];

    if(ac==1)
    {
        fprintf(stderr,"it's wrong!\n");
        exit(1);
    }
    sock=make_server_socket(atoi(av[1]));
    if(sock==-1)
    {
        printf("error\n");
    }

    while(1)
    {

/*accept*/
        fd=accept(sock,NULL,NULL);
        fpin=fdopen(fd,"r");

        fgets(request,BUFSIZ,fpin);
        printf("got a call:request:%s",request);
        read_til_crnl(fpin);
        process_rq(request,fd);
        fclose(fpin);
    }
}

read_til_crnl(FILE *fp)
{
    char buf[BUFSIZ];
    while(fgets(buf,BUFSIZ,fp)!=NULL&&strcmp(buf,"\r\n")!=0)
        ;
}

process_rq(char *rq,int fd)
{
    char cmd[BUFSIZ],arg[BUFSIZ];
    if(fork()!=0)
        return ;
    strcpy(arg,"./");
    if(sscanf(rq,"%s%s",cmd,arg+2)!=2)
        return ;
    if(strcmp(cmd,"GET")!=0)
        cannot_do(fd);
    else if(not_exist(arg))
        do_404(arg,fd);
    else if(isadir(arg))
        do_ls(arg,fd);
    else if(ends_in_cgi(arg))
        do_exec(arg,fd);
    else
        do_cat(arg,fd);
}

void header(FILE *fp,char *content_type)
{
    fprintf(fp,"HTTP/1.0 200 OK\r\n");
    if(content_type)
        fprintf(fp,"Content-type: %s\r\n",content_type);
}

cannot_do(int fd)
{
    FILE *fp=fdopen(fd,"w");

    fprintf(fp,"HTTP/1.0 501 Not Implemented\r\n");
    fprintf(fp,"Content-type: text/plain\r\n");
    fprintf(fp,"\r\n");
    fprintf(fp,"That command is not yet implemented\r\n");
    fclose(fp);
}



do_404(char *item,int fd)
{
    struct utsname uts;
    if(uname(&uts)==-1)
    {
        fprintf(stderr,"can't uname\r\n");
    }
    FILE *fp=fdopen(fd,"w");

    fprintf(fp,"HTTP/1.0 404 Not Found\r\n");
    fprintf(fp,"Content-type: text/plain\r\n");
    fprintf(fp,"\r\n");

    fprintf(fp,"The Page Not Found\r\n");
    fprintf(fp,"The kernel Version is %s-%s\r\n",uts.sysname,uts.release);
    fclose(fp);
}

isadir(char *f)
{
    struct stat info;
    return (stat(f,&info)!=-1&&S_ISDIR(info.st_mode));
}

not_exist(char *f)
{
    struct stat info;
    return (stat(f,&info)==-1);
}

do_ls(char *dir, int fd)
{
    FILE *fp;
    fp=fdopen(fd,"w");
    header(fp,"text/plain");
    fprintf(fp,"\r\n");
    fflush(fp);

    dup2(fp,1);
    dup2(fp,2);
    close(fd);
    execlp("ls","ls","-l",dir,NULL);
    perror(dir);
    exit(1);
}

char * file_type(char *f)
{
    char *cp;
    if((cp=strrchr(f,'.'))!=NULL)
        return cp+1;
    return "";
}

ends_in_cgi(char *f)
{
    return (strcmp(file_type(f),"cgi")==0);
}

do_exec(char * prog,int fd)
{
    FILE *fp;
    fp=fdopen(fd,"w");
    header(fp,NULL);
    fflush(fp);
    dup2(fd,1);
    dup2(fd,2);
    close(fd);
    execl(prog,prog,NULL);
    perror(prog);
}

do_cat(char *f,int fd)
{
    char *extension=file_type(f);
    char *content="text/plain";
    FILE *fpsock,*fpfile;
    int c;

    if(strcmp(extension,"html")==0)
        content="text/html";
    else if(strcmp(extension,"gif")==0)
        content="image/gif";
    else if(strcmp(extension,"jpg")==0)
        content="image/jpeg";
    else if(strcmp(extension,"jpeg")==0)
        content="image/jpeg";

    fpsock=fdopen(fd,"w");
    fpfile=fopen(f,"r");

    if(fpsock!=NULL,fpfile!=NULL)
    {
        header(fpsock,content);
        fprintf(fpsock,"\r\n");
        while((c=getc(fpfile))!=EOF)
            putc(c,fpsock);
        fclose(fpfile);
        fclose(fpsock);
    }
    exit(0);
}

阅读(4045) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~