首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

简略http_server的C语言实现

2012-12-21 
简单http_server的C语言实现主要实现以下几点:1.静态文件访问,包括jpg、html、css等2.文件不存在4043.目录列

简单http_server的C语言实现
主要实现以下几点:

1.静态文件访问,包括jpg、html、css等

2.文件不存在404

3.目录列表

4.501 Not Implemented

=============================================================================

启动脚本

#!/bin/shps -ef | grep fasthttp | grep -v grep | awk '{print $2}' | xargs -t -i kill -9 {} >/dev/nullgcc   fasthttp.c -o fasthttp$(pwd)/fasthttp


以下是源码

=====================================================================================
#include <string.h>#include <stdio.h>#include <stdlib.h>#include <netinet/in.h>#include <error.h>#include <errno.h>#include <sys/types.h>#include <dirent.h>#include <sys/socket.h>#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>// 建立socket 开始侦听 接收连接 接收客户端数据 解析http协议 发送文件数据给客户端#define HTTP_PORT "2010"#define MAX_CONNECTION 10#define DOCUMENT_ROOT "www"#define LOG_PATH "log/access.log"void parser(char *s,char res[][255],char host[][255]);static char *strtoupper( char *s );static long filesize(const char *filename);static int file_exists(const char *filename);static void mime_content_type( const char *name, char *ret );static int WriteLog( const char *message );static int is_dir(const char *filename);static unsigned short g_is_log        = 1;static int g_log_fd                    = 0;int main(void){    int server_sock;    int client_sock;    struct sockaddr_in server_addr;    struct sockaddr_in client_addr;    struct sockaddr_in sin;    struct stat file_stat;    pid_t pid;    char client_ip[100];    char buf[20000];    char buf_all[2000];    char buf1[2000];    char p[3][255];    char h[3][255];    char tmp[2000];    char cwd[1024];    char filename[2000];    char filepath[2000];    int fd,size;    int currentConn = 0;        DIR * dir;    struct dirent * ptr;        chdir("../");        if ( (pid = fork()) < 0 )    {        perror("fork");        exit(1);    }    else if ( pid != 0)    {        exit(1);    }        if((server_sock = socket(AF_INET,SOCK_STREAM,0)) < 0)    {        perror("socket");        exit(1);    }        memset(&server_addr,0,sizeof(server_addr));    server_addr.sin_family = AF_INET;    server_addr.sin_port = htons(atoi(HTTP_PORT));    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);        if(bind(server_sock,(struct sockaddr*)&server_addr,sizeof(server_addr)) < 0)    {        perror("bind");        exit(1);    }        if(listen(server_sock,MAX_CONNECTION) < 0)    {        perror("listen");        exit(1);    }        printf("fasthttp successful created ...\n");        while(1)    {        unsigned int clientlen = sizeof(client_addr);        if((client_sock = accept(server_sock,(struct sockaddr*)&client_addr,&clientlen)) < 0)        {            perror("accept");            exit(1);        }                if((pid = fork()) == 0)        {            if(read(client_sock,buf,20000) < 0)            {                perror("read data from client");                exit(1);            }                        parser(buf,p,h);                        if(strcmp(strtoupper(p[0]),"GET") != 0                && strcmp(strtoupper(p[0]),"POST") != 0                && strcmp(strtoupper(p[0]),"HEAD") != 0)            {                memset(&buf,0,sizeof(buf));                                sprintf(buf, "HTTP/1.1 501 Not Implemented\r\nServer: %s\r\nContent-Type: text/html\r\nContent-Length:    1489\r\nAccept-Ranges: bytes\r\nConnection: close\r\n\r\n", "Apache");                write(client_sock,buf,strlen(buf));                                memset(&buf,0,sizeof(buf));                sprintf(buf,"<h2>%s Method Not Implemented</h2>","501");                write(client_sock,buf,strlen(buf));                close(client_sock);                exit(0);            }                         if(strcmp(p[1],"/") == 0)            {                memset(&tmp,0,sizeof(tmp));                sprintf(tmp,"%s","index.html");                strcat(p[1],tmp);            }                        WriteLog(p[1]);            getcwd(filepath, sizeof(filepath));            strcat(filepath,"/");            strcat(filepath,DOCUMENT_ROOT);             strcat(filepath,p[1]);            if(!file_exists(filepath))            {                memset(&buf,0,sizeof(buf));                sprintf(buf, "HTTP/1.1 404 Not Found\r\nServer: %s\r\nContent-Type: text/html\r\nContent-Length:    257271\r\nConnection: close\r\n\r\n", "Apache");                write(client_sock,buf,strlen(buf));                                memset(&buf,0,sizeof(buf));                sprintf(buf,"<html><head><title>404 Not Found</title></head><body bgcolor="white"><center><h1>404 Not Found</h1></center><hr><center>Powered by %s</center></body></html>","fasthttp");                write(client_sock,buf,strlen(buf));                close(client_sock);                                memset(&buf,0,sizeof(buf));                sprintf(buf,"404 Not Found\t%s\n",filepath);                WriteLog(buf);                                exit(0);            }                        if(access(filepath,R_OK) < 0)            {                memset(&buf,0,sizeof(buf));                sprintf(buf, "HTTP/1.1 403 Forbidden\r\nServer: %s\r\nContent-Type: text/html\r\nContent-Length:    25727\r\nConnection: close\r\n\r\n", "Apache");                write(client_sock,buf,strlen(buf));                close(client_sock);                exit(0);            }                         /** 目录列表 **/             if(is_dir(filepath))             {                memset(&tmp,0,sizeof(tmp));                sprintf(tmp,"<html><head><title>Index of %s</title></head><body><h1>Index of %s</h1><ul><li><a href="/"> Parent Directory</a></li>",filepath,filepath);                strcat(buf,tmp);                 if((dir = opendir(filepath)) != NULL)                 {                     while((ptr = readdir(dir)) != NULL)                     {                                                  if(strcmp(ptr->d_name,".") == 0 || strcmp(ptr->d_name,"..") == 0)                         {                             continue;                             }                                                  memset(&buf,0,sizeof(buf));                         sprintf(buf,"%s/%s",filepath,ptr->d_name);                                                if(is_dir(buf))                        {                            memset(&buf,0,sizeof(buf));                            sprintf(buf,"<li><a href="%s/"> %s/</a></li>",ptr->d_name,ptr->d_name);                        }                        else                        {                            memset(&buf,0,sizeof(buf));                            sprintf(buf,"<li><a href="%s"> %s</a></li>",ptr->d_name,ptr->d_name);                            }                        strcat(tmp,buf);                     }                 }                 closedir(dir);                 memset(&buf,0,sizeof(buf));                sprintf(buf,"%s","</ul>");                strcat(tmp,buf);                                memset(&buf,0,sizeof(buf));                sprintf(buf, "HTTP/1.1 200 OK\r\nServer: fasthttp\r\nContent-Type: text/html;charset=utf-8\r\nContent-Length:    %d\r\nConnection: close\r\n\r\n", strlen(tmp));                write(client_sock,buf,strlen(buf));                            write(client_sock,tmp,strlen(tmp));                close(client_sock);             }                         memset(&tmp,0,sizeof(tmp));            mime_content_type(filepath,tmp);                        memset(&buf,0,sizeof(buf));            sprintf(buf, "HTTP/1.1 200 OK\r\nServer: %s\r\nContent-Type: %s\r\nContent-Length:    25727\r\nConnection: close\r\n\r\n", "Apache",tmp);            write(client_sock,buf,strlen(buf));                                                memset(&buf,0,sizeof(buf));            fd = open(filepath,O_RDONLY);            read(fd,buf,filesize(filepath));            close(fd);                        write(client_sock,buf,filesize(filepath));            close(client_sock);                        memset(&buf,0,sizeof(buf));            sprintf(buf,"200 OK\t%s\t%d\n",filepath,filesize(filepath));            WriteLog(buf);                        exit(0);        }        else        {            wait(NULL);        }                close(client_sock);    }        }void parser(char *s,char res[][255],char host[][255]){    int i,j = 0;    int n;    char hosts[255];    for (i = 0;s[i] != '\r';i++)        /* obtain the first line in http protocol head */        ;    s[i] = '\0';    n=i++;        for (i = 0,j = 0;i < 3;i++,j++)        /* divide the protocol head in blank */    {        strcpy(res[j],strsep(&s," "));    }        for(i=n;s[i] != '\r';i++)    {        strcat(hosts,s[i]);    }        for (i = 0,j = 0;i < 3;i++,j++)        /* divide the protocol head in blank */    {        strcpy(host[j],strsep(&hosts,":"));    }    }/** * strtoupper - string to upper * */static char *strtoupper( char *s ){    int i, len = sizeof(s);    for( i = 0; i < len; i++ )    {        s[i] = ( s[i] >= 'a' && s[i] <= 'z' ? s[i] + 'A' - 'a' : s[i] );    }        return(s);}/** *  filesize - get file size */static long filesize(const char *filename){    struct stat buf;    if (!stat(filename, &buf))    {        return buf.st_size;    }    return 0;}/** * file_exists - check file is exist */static int file_exists(const char *filename){    struct stat buf;        if (stat(filename, &buf) < 0)    {        if (errno == ENOENT)        {            return 0;        }    }    return 1;}/** * Get MIME type header * */static void mime_content_type( const char *name, char *ret ){    char *dot, *buf;    dot = strrchr(name, '.');    /* Text */    if ( strcmp(dot, ".txt") == 0 ){        buf = "text/plain";    } else if ( strcmp( dot, ".css" ) == 0 ){        buf = "text/css";    } else if ( strcmp( dot, ".js" ) == 0 ){        buf = "text/javascript";    } else if ( strcmp(dot, ".xml") == 0 || strcmp(dot, ".xsl") == 0 ){        buf = "text/xml";    } else if ( strcmp(dot, ".xhtm") == 0 || strcmp(dot, ".xhtml") == 0 || strcmp(dot, ".xht") == 0 ){        buf = "application/xhtml+xml";    } else if ( strcmp(dot, ".html") == 0 || strcmp(dot, ".htm") == 0 || strcmp(dot, ".shtml") == 0 || strcmp(dot, ".hts") == 0 ){        buf = "text/html";    /* Images */    } else if ( strcmp( dot, ".gif" ) == 0 ){        buf = "image/gif";    } else if ( strcmp( dot, ".png" ) == 0 ){        buf = "image/png";    } else if ( strcmp( dot, ".bmp" ) == 0 ){        buf = "application/x-MS-bmp";    } else if ( strcmp( dot, ".jpg" ) == 0 || strcmp( dot, ".jpeg" ) == 0 || strcmp( dot, ".jpe" ) == 0 || strcmp( dot, ".jpz" ) == 0 ){        buf = "image/jpeg";    /* Audio & Video */    } else if ( strcmp( dot, ".wav" ) == 0 ){        buf = "audio/wav";    } else if ( strcmp( dot, ".wma" ) == 0 ){        buf = "audio/x-ms-wma";    } else if ( strcmp( dot, ".wmv" ) == 0 ){        buf = "audio/x-ms-wmv";    } else if ( strcmp( dot, ".au" ) == 0 || strcmp( dot, ".snd" ) == 0 ){        buf = "audio/basic";    } else if ( strcmp( dot, ".midi" ) == 0 || strcmp( dot, ".mid" ) == 0 ){        buf = "audio/midi";    } else if ( strcmp( dot, ".mp3" ) == 0 || strcmp( dot, ".mp2" ) == 0 ){        buf = "audio/x-mpeg";    } else if ( strcmp( dot, ".rm" ) == 0  || strcmp( dot, ".rmvb" ) == 0 || strcmp( dot, ".rmm" ) == 0 ){        buf = "audio/x-pn-realaudio";    } else if ( strcmp( dot, ".avi" ) == 0 ){        buf = "video/x-msvideo";    } else if ( strcmp( dot, ".3gp" ) == 0 ){        buf = "video/3gpp";    } else if ( strcmp( dot, ".mov" ) == 0 ){        buf = "video/quicktime";    } else if ( strcmp( dot, ".wmx" ) == 0 ){        buf = "video/x-ms-wmx";    } else if ( strcmp( dot, ".asf" ) == 0  || strcmp( dot, ".asx" ) == 0 ){        buf = "video/x-ms-asf";    } else if ( strcmp( dot, ".mp4" ) == 0 || strcmp( dot, ".mpg4" ) == 0 ){        buf = "video/mp4";    } else if ( strcmp( dot, ".mpe" ) == 0  || strcmp( dot, ".mpeg" ) == 0 || strcmp( dot, ".mpg" ) == 0 || strcmp( dot, ".mpga" ) == 0 ){        buf = "video/mpeg";    /* Documents */    } else if ( strcmp( dot, ".pdf" ) == 0 ){        buf = "application/pdf";    } else if ( strcmp( dot, ".rtf" ) == 0 ){        buf = "application/rtf";    } else if ( strcmp( dot, ".doc" ) == 0  || strcmp( dot, ".dot" ) == 0 ){        buf = "application/msword";    } else if ( strcmp( dot, ".xls" ) == 0  || strcmp( dot, ".xla" ) == 0 ){        buf = "application/msexcel";    } else if ( strcmp( dot, ".hlp" ) == 0  || strcmp( dot, ".chm" ) == 0 ){        buf = "application/mshelp";    } else if ( strcmp( dot, ".swf" ) == 0  || strcmp( dot, ".swfl" ) == 0 || strcmp( dot, ".cab" ) == 0 ){        buf = "application/x-shockwave-flash";    } else if ( strcmp( dot, ".ppt" ) == 0  || strcmp( dot, ".ppz" ) == 0 || strcmp( dot, ".pps" ) == 0 || strcmp( dot, ".pot" ) == 0 ){        buf = "application/mspowerpoint";    /* Binary & Packages */    } else if ( strcmp( dot, ".zip" ) == 0 ){        buf = "application/zip";    } else if ( strcmp( dot, ".rar" ) == 0 ){        buf = "application/x-rar-compressed";    } else if ( strcmp( dot, ".gz" ) == 0 ){        buf = "application/x-gzip";    } else if ( strcmp( dot, ".jar" ) == 0 ){        buf = "application/java-archive";    } else if ( strcmp( dot, ".tgz" ) == 0  || strcmp( dot, ".tar" ) == 0 ){        buf = "application/x-tar";    } else {        buf = "application/octet-stream";    }    strcpy(ret, buf);}/** * Log message * */static int WriteLog( const char *message ){    if ( !g_is_log )    {        fprintf(stderr, "%s", message);        return 0;    }    if ( g_log_fd == 0 )    {        char g_log_path[2000];        getcwd(g_log_path, sizeof(g_log_path));        strcat(g_log_path,"/");        strcat(g_log_path,LOG_PATH);                if ( (g_log_fd = open(g_log_path, O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1 )        {            perror("open log file error");            return -1;        }    }        if (write(g_log_fd, message, strlen(message)) == -1)    {        perror("write log error");        return -1;    }    return 0;}/** * is_dir - check file is directory * */static int is_dir(const char *filename){    struct stat buf;    if ( stat(filename, &buf) < 0 ){        return -1;    }    if (S_ISDIR(buf.st_mode)){        return 1;    }    return 0;}

热点排行