基于HTTP和大数运算的在线计算器

关于HTTP的具体的描述网上一大堆本文不在赘述

基于HTTP和大数运算的在线计算器_第1张图片

#include "http.h"


int starup(const char* ip,int port)
{
    int sock = socket(AF_INET,SOCK_STREAM,0);
    if(sock < 0)
    {
        perror("socket");
        return -1;
    }

    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_port = htons(port);
    server.sin_addr.s_addr = inet_addr(ip);
    int opt = 1;
    setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
    if(bind(sock,(struct sockaddr*)&server,sizeof(server)) < 0)
    {
        perror("bind");
        return -2;
    }

    if(listen(sock,10) < 0)
    {
        perror("listen");
        return -3;
    }

    return sock;
}

static ssize_t Getline(int fd,char* buf,int size)
{
    char c = 0;
    int len = 0;

    while(c != '\n' && len < size - 1)
    {
        ssize_t s = recv(fd,&c,1,0);
        if(s > 0)
        {
            if('\r' == c)
            {
                recv(fd,&c,1,MSG_PEEK);
                if('\n' == c)// \r  \r\n  \ra
                {
                    recv(fd,&c,1,0);
                }
                else
                {
                    c = '\n';
                }
            }

            buf[len++]=c;
        }
    }

    buf[len] = 0;
    return len;
}

static drop_header(int fd)
{
    int ret = -1;
    char buf[SIZE];
    do
    {
        ret = Getline(fd,buf,SIZE);
    }while(ret > 0 && strcmp(buf,"\n"));
}

int echo_www(int fd,const char* path,int size)
{
    int new_fd = open(path,O_RDONLY);
    if (new_fd < 0)
    {
        perror("open");
        print_log("open file error!",FATAL);
        return 404;
    }

    const char* echo_line = "HTTP/1.0 200 OK\r\n";
    const char* blank_line = "\r\n";
    send(fd,echo_line,strlen(echo_line),0);
    send(fd,blank_line,strlen(blank_line),0);

    if(sendfile(fd,new_fd,NULL,size) < 0)
    {
        print_log("send file error!",FATAL);
        return 200;
    }

    close(new_fd);
}

void print_log(const char* msg,int lev)
{
    int fd = open("/log/errorfile",O_WRONLY);
    if (fd < 0)
    {
        return;
    }

    time_t timer;
    struct tm *local;
    timer = time(NULL);
    local = localtime(&timer);
    const char* strlocaltime = asctime(local);
    char buf[SIZE];
    strcpy(buf,strlocaltime);
    const char* blank = ": ";
    strcat(buf,blank);
    strcat(buf,msg);
    strcat(buf,blank);
    write(fd,buf,strlen(buf));
    write(fd,&lev,sizeof(lev));
    write(fd,"\n",1);
    close(fd);
}

void echo_error(int fd,int errno_num)
{
    const char* _400 = "400 bad request";
    const char* _401 = "401 Unauthorized";
    const char* _403 = "403 Forbidden";
    const char* _404 = "404 not found";
    const char* _500 = "Internal Server Error";
    const char* _503 = "503 Server Unavailable";
    switch(errno_num)
    {
    case 400:
        send(fd,_400,strlen(_400),0);
        break;    
    case 401:
        send(fd,_401,strlen(_401),0);
        break;    
    case 403:
        send(fd,_403,strlen(_403),0);
        break;    
    case 404:
        send(fd,_404,strlen(_404),0);
        break;    
    case 500:
        send(fd,_500,strlen(_500),0);
        break;    
    case 503:
        send(fd,_503,strlen(_503),0);
        break;    
    default:
        break;
    }
}

int exe_cgi(int fd,const char* method,const char* path,const char* query_string)
{
    int content_len = -1;
    char METHOD[SIZE];
    char QUERY_STRING[SIZE];
    char CONTENT_LENGTH[SIZE];
    if(strcasecmp(method,"GET") == 0)
    {
        drop_header(fd);
    }
    else
    {
        char buf[SIZE];
        int ret = -1;
        do
        {
            ret = Getline(fd,buf,sizeof(buf));
            if(strncasecmp(buf,"CONTENT_LENGTH: ",16) == 0)
            {
                content_len = atoi(&buf[16]);
            }
        }while(ret > 0 && strcmp(buf,"\n"));
        if(content_len == -1)
        {
            echo_errno(fd,401);
            return -1;
        }
    }//method
    //printf("cgi path:%s",path);
    int input[2];
    int output[2];
    if(pipe(input) < 0)
    {
        echo_errno(fd,501);
        return -2;
    }
    if(pipe(output) < 0)
    {
        echo_errno(fd,501);
        return -3;
    }

    const char* echo_line = "HTTP/1.0 200 OK\r\n";
    const char* type = "Content-Type:text/html;charset=ISO-8859-1\r\n";
    const char* blank_line = "\r\n";
    send(fd,echo_line,strlen(echo_line),0);
    send(fd,type,strlen(type),0);
    send(fd,blank_line,strlen(blank_line),0);

    pid_t id = fork();
    if(id < 0)
    {
        echo_errno(fd,401);
        return -4;
    }
    else if(id == 0)
    {
        close(input[1]);
        close(output[0]);
        sprintf(METHOD,"METHOD=%s",method);
        putenv(METHOD);
        if(strcasecmp(method,"GET") == 0)
        {
            sprintf(QUERY_STRING,"QUERY_STRING=%s",query_string);
            putenv(QUERY_STRING);
        }
        else
        {
            sprintf(CONTENT_LENGTH,"CONTENT_LENGTH=%d",content_len);
            putenv(CONTENT_LENGTH);
        }
        dup2(input[0],0);
        dup2(output[1],1);
        execl(path,path,NULL);
        exit(1);
    }
    else
    {
        close(input[0]);
        close(output[1]);
        int i = 0;
        char c = 0;
        for(;i < content_len; i++)
        {
            recv(fd,&c,1,0);
            write(input[1],&c,1);
        }

        while(1)
        {
            ssize_t s = read(output[0],&c,1);
            if(s > 0)
            {
                send(fd,&c,1,0);
            }
            else
            {
                break;
            }
        }
        waitpid(id,NULL,0);
        close(input[1]);
        close(output[0]);
    }//fork
}


void* http_service(void* arg)
{

    //printf("release\n");
    int errno_num = 0;
    int cgi = 0;
    char buf[SIZE] = {0};
    char method[SIZE/8]={0};
    char url[SIZE]={0};
    char path[SIZE];
    char* query_string = NULL;
    int ret = Getline(fd,buf,sizeof(buf));
    if(ret < 0)
        goto end;
    int i=0,j=0;
    while(i < sizeof(method) && j < sizeof(buf) && !isspace(buf[j]))
    {
        method[i++] = buf[j++]; 
    }
    method[i] = 0;
    i = 0;
    while(isspace(buf[j]) && j < sizeof(buf))
        j++;
    while(i < sizeof(url) && j < sizeof(buf) && !isspace(buf[j]))
    {
        url[i++] = buf[j++];
    }
    url[i] = 0;
    printf("method=%s,url=%s\n",method,url);

    if (strcasecmp(method,"GET") && strcasecmp(method,"POST"))
    {
        print_log("method is not ok\n",FATAL);
        errno_num = 401;
        goto end;
    }

    if (strcasecmp(method,"POST") == 0)
    {
        cgi = 1;
    }
    query_string=url;
    while(*query_string != 0)
    {
        if(*query_string == '?')
        {
            cgi = 1;
            *query_string = 0;
            query_string++;
            break;
        }
        query_string++;
    }

    sprintf(path,"wwwroot%s",url);
    if (path[strlen(path) - 1] == '/')
    {
        strcat(path,"index.html");
    }
    //printf("%s\n",path);

    struct stat st;
    if(stat(path,&st) < 0)
    {
        errno_num = 404;
        print_log("path not found",FATAL);
        goto end;
    }
    else if(S_ISDIR(st.st_mode))
    {
        strcat(path,"index.html");
    }
    else if((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH))
    {
        cgi = 1;
    }

    if(cgi)
    {
        exe_cgi(fd,method,path,query_string);
    }
    else
    {
      drop_header(fd);
      errno_num = echo_www(fd,path,st.st_size);
    }

end:
    echo_errno(fd,errno_num);
    close(fd);
}
#include 
#include 
#include 
#include "rnp.hpp"

#define SIZE 1024


static void UTF_8ToASCII(const string& str,string& ascstr)
{
    size_t i = 0;
    while(str[i] != '=')
        i++;
    i++;
    for(; i < str.length(); i++)
    {
        if(str[i] >= '0' && str[i] <= '9')
            ascstr+=str[i];
        else if(str[i] == '*' || str[i] == '-')
            ascstr+=str[i];
        else if(str[i] == '%')
        {
            i+=2;
            switch(str[i])
            {
            case 'B':
                ascstr+='+';
                break;    
            case 'F':
                ascstr+='/';
                break;
            case '5':
                ascstr+='%';
                break;
            default:
                break;
            }
        }
    }
}

void math_cgi(string str)
{

    string ascstr;
    UTF_8ToASCII(str,ascstr);
    cout<" = ";
    BigNumber num = RNPexpprssion(ascstr);
    cout<int main()
{
   //printf("

hollo math-cgi

");
char* method = NULL; char* query_string = NULL; char* content_length = NULL; char info[SIZE]; int i = 0; method = getenv("METHOD"); if(method == NULL) { printf("get method error\n"); return -1; } if(strcasecmp(method,"GET") == 0) { query_string = getenv("QUERY_STRING"); if(query_string == NULL) { printf("get method GET error\n"); return -2; } strcpy(info,query_string); } else if(strcasecmp(method,"POST") == 0) { content_length = getenv("CONTENT_LENGTH"); if(content_length == NULL) { printf("get CONTENT_LENGTH errno\n"); return -3; } char c = 0; for(;i < atoi(content_length); i++) { read(0,&c,1); info[i]=c; } } else { printf("method error\n"); return -4; } math_cgi(info); return 0; }

大数运算
http://blog.csdn.net/Dakuan_chen/article/details/76164684

你可能感兴趣的:(项目经验,linux网络编程)