HTTP服务器加强版

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HTTP服务器加强版相关的知识,希望对你有一定的参考价值。

与上一篇不同,本篇添加了大数据处理,对数据库的操作(增删查改)

以下注释均为测试,可忽略

绿色为文件蓝色为目录

这是整体的一个目录:

技术分享


conf/server.conf:

IP:127.0.0.1
PORT:8080

htdocs/index.html:(数据库操作)

<html>
    <head>                                                                      
        <h1>hello,this is database</h1>
        <h2>you can choose a operoter...</h2>
    </head>
    <body>
        <h2>INSERT</h2>
            <form action="mysql_connect/sql_api" method="POST">
                name   :<input type="text" name="name"/><br/>
                sex    :<input type="text" name="sex"/><br/>
                age    :<input type="text" name="age"/><br/>
                tel    :<input type="text" name="tel"/><br/>
                school :<input type="text" name="school"/><br/>
                <input type="submit" value="insert"/><br/>
            </form>
        <h2>SELECT</h2>     
        <h2>you can choose one or zero ...</h2>
           <form action="mysql_connect/sql_api" method="GET">
                select_name   :<input type="text" name="select_name"/><br/>
                select_sex    :<input type="text" name="select_sex"/><br/>
                select_age    :<input type="text" name="select_age"/><br/>
                select_tel    :<input type="text" name="select_tel"/><br/>
                select_school :<input type="text" name="select_school"/><br/>
                select_id     :<input type="text" name="select_id"/><br/>
                <input type="submit" value="select data"/><br/>
            </form>
        <h2>DELETE</h2>
        <h2>you can choose one or zero ...</h2>
             <form action="mysql_connect/sql_api" method="GET">
                 delete_name  :<input type="text" name="delete_name"/><br/>
                 delete_sex   :<input type="text" name="delete_sex"/><br/>
                 delete_age   :<input type="text" name="delete_age"/><br/>      
                 delete_tel   :<input type="text" name="delete_tel"/><br/>
                 delete_school:<input type="text" name="delete_school"/><br/>
                 delete_id    :<input type="text" name="delete_id"/><br/>
                 <input type="submit" value="delete"/><br/>
             </form>
        <h2>UPDATE</h2>
            <form action="mysql_connect/sql_api" method="GET">
                 updata_name  :<input type="text" name="updata_name1"/>
                 <input type="text" name="updata_name2"/><br/>                  
                 updata_sex   :<input type="text" name="updata_sex1"/>
                 <input type="text" name="updata_sex1"/><br/>
                 updata_age   :<input type="text" name="updata_age"/>
                 <input type="text" name="updata_age"/><br/>
                 updata_tel   :<input type="text" name="updata_tel"/>
                 <input type="text" name="updata_tel"/><br/>
                 updata_school:<input type="text" name="updata_school"/>
                 <input type="text" name="updata_school"/><br/>
                 <input type="submit" value="updata"/><br/>
            </form>
        <img src="10.jpg" alt="mantouheqi" dth="200" height="300"/>
    </body>
</html>

htdocs/mysql_connect/main.cpp:

#include "sql_api.h"
 
void get_args(std::vector<std::string> &vec,std::string &op)                    
{
    std::string method=getenv("METHOD");//getenv return NULL to string is error
    std::string query_string;
    std::string content_length;
    char ch=‘a‘;
    int index=0;
    int ret=-1;
    char buf[_SIZE_];
    memset(buf,‘\0‘,sizeof(buf));
    if(method=="POST"){//POST
        std::string content_length=getenv("CONTENT_LENGTH");
        int len=atoi(content_length.c_str());
        memset(buf,‘\0‘,sizeof(buf));
        while(len){//&& index<sizeof(buf)-1){
            ret=read(0,&ch,1);
            buf[index++]=ch;
            len--;
        }
        if(len!=0){
            printf("error!\n");
            return;
        }
    }else{//GET
        query_string=getenv("QUERY_STRING");
        strcpy(buf,query_string.c_str());
        index=query_string.size();
    }
    buf[index]=‘\0‘;
//  std::cout<<buf<<std::endl;
    if(strncmp(buf,"name",4)==0){
        op="insert";
    }else if(strncmp(buf,"select_name",11)==0){
        op="select";
    }else if(strncmp(buf,"delete_name",11)==0){
        op="delete";
    }else if(strncmp(buf,"updata_name",11)==0){                                 
        op="updata";
    }
//  std::cout<<op<<std::endl;
    char *end=buf+index;
    int incount=0;
    while(end!=buf){
        if(*end == ‘=‘){
            vec.push_back(end+1);
        }
        if(*end == ‘&‘){
            *end=‘\0‘;
        }
        end--;
    }
}

void insert_echo_html()
{   
    std::cout<<"HTTP/1.1 200 OK\r\n\r\n";
    std::cout<<"<html>"<<std::endl;
    std::cout<<"<head>"<<std::endl;
    std::cout<<"<h1>insert success!</h1>"<<std::endl;
    std::cout<<"</head>"<<std::endl;
    std::cout<<"</html>"<<std::endl;
}   
    
void delete_echo_html()
{   
    std::cout<<"HTTP/1.1 200 OK\r\n\r\n";
    std::cout<<"<html>"<<std::endl;
    std::cout<<"<head>"<<std::endl;
    std::cout<<"<h1>delete success!</h1>"<<std::endl;
    std::cout<<"</head>"<<std::endl;                                            
    std::cout<<"</html>"<<std::endl;
}   
 
void updata_echo_html()
{   
    std::cout<<"HTTP/1.1 200 OK\r\n\r\n";
    std::cout<<"<html>"<<std::endl;                                             
    std::cout<<"<head>"<<std::endl;
    std::cout<<"<h1>updata success!</h1>"<<std::endl;
    std::cout<<"</head>"<<std::endl;
    std::cout<<"</html>"<<std::endl;
}   
    
void failed_echo_html()
{   
    std::cout<<"HTTP/1.1 200 OK\r\n\r\n";
    std::cout<<"<html>"<<std::endl;
    std::cout<<"<head>"<<std::endl;
    std::cout<<"<h1>operator failed!Info Is Not Exit or Your Can Check Your Args...</h1>"<<std::endl;
    std::cout<<"</head>"<<std::endl;
    std::cout<<"</html>"<<std::endl;
}   
int main()
{   
    std::vector<std::string> vec;
    std::string op;
    get_args(vec,op);
    
    int vec_size=vec.size();
    const char *name=vec[vec_size-1].c_str();
    const char *sex=vec[vec_size-2].c_str();
    const char *age=vec[vec_size-3].c_str();
    const char *tel=vec[vec_size-4].c_str();
    const char *school=vec[vec_size-5].c_str();
    const char *id=vec[vec_size-6].c_str();
    
    mysql_api sql;                                                              
    //连接到MYSQL服务器
    sql.mysql_connect_sql();
    
    bool ret=false;
    if(op=="insert"){
        ret=sql.mysql_insert(name,sex,age,tel,school);
        if(ret==true){
            ret=false;
            insert_echo_html();
        }else{
            failed_echo_html();
        }
    }else if(op=="select"){
        ret=sql.mysql_select(id,name,sex,age,tel,school);
        if(ret==true){
            ret=false;
        }else{
            failed_echo_html();                                                 
        }
    }else if(op=="delete"){
//      std::cout<<op<<std::endl;
        ret=sql.mysql_delete(id,name,sex,age,tel,school);
        if(ret==true){
            ret=false;
            delete_echo_html();
        }else{
            failed_echo_html();
        }
    }else if(op=="updata"){
        const char *oldname=vec[vec_size-1].c_str();
        const char *newname=vec[vec_size-2].c_str();
        const char *oldsex=vec[vec_size-3].c_str();
        const char *newsex=vec[vec_size-4].c_str();
        const char *oldage=vec[vec_size-5].c_str();
        const char *newage=vec[vec_size-6].c_str();
        const char *oldtel=vec[vec_size-7].c_str();
        const char *newtel=vec[vec_size-8].c_str();
        const char *oldschool=vec[vec_size-9].c_str();
        const char *newschool=vec[vec_size-10].c_str();                         
    
        ret=sql.mysql_updata(oldname,newname,oldsex,newsex,oldage,newage,oldtel,newtel,oldschool,newschool);
        if(ret==true){
            ret=false;
            updata_echo_html();
         }else{
            failed_echo_html();
        }
    }
    
    sql.mysql_close_sql();                                                      
    
    return 0;
}

htdocs/mysql_connect/sql_api.h:

#include <iostream>
#include <string>
#include <vector>                                                               
#include <mysql.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
 
#define _SIZE_ 2048
 
class mysql_api
{
public:
    mysql_api();
    void mysql_connect_sql();
    bool mysql_select(std::string id="",std::string name="",std::string sex="",std::string age="",std::string tel="",std::string school="");
    bool mysql_insert(std::string name,std::string sex,std::string age,std::string tel,std::string school);
    bool mysql_delete(std::string id="",std::string name="",std::string sex="",std::string age="",std::string tel="",std::string school="");
    bool mysql_updata(std::string oldname="",std::string newname="",std::string oldsex="",std::string newsex="",\  std::string oldage="",std::string newage="",std::string oldtel="",std::string newtel="",std::string oldschool="",std::string newschool="");
    bool mysql_close_sql();
    ~mysql_api();
private:
    bool _sql_op(std::string &sql_op);
    bool _select_data();
private:
    MYSQL mysql;
    std::string host;                                                           
    std::string user;
    std::string passwd;
    std::string db;
    unsigned int port;
    unsigned long client_flag;
};

htdocs/mysql_connect/sql_api.cpp:

#include "sql_api.h"
 
mysql_api::mysql_api()                                                          
    :host("127.0.0.1")
    ,user("root")
    ,passwd("密码")
    ,db("9_students")
    ,port(3306)
    ,client_flag(0)
{
    //获得或初始化一个MYSQL结构
    mysql_init(&mysql);
}
void mysql_api::mysql_connect_sql()
{
    //连接到MYSQL服务器
    mysql_real_connect(&mysql,host.c_str(),user.c_str(),passwd.c_str(),db.c_str(),port,NULL,0);
}
bool mysql_api::mysql_select(std::string id,std::string name,std::string sex,std::string age,std::string tel,std::string school)
{
    //select 列名称 from 表名称 [查询条件];
    std::string sql_op="select * from students where ";
    if(name!=""){
        sql_op.append("name=\"");
        sql_op.append(name);
        sql_op.append("\"");
    }else if(sex!=""){
        sql_op.append("sex=\"");
        sql_op.append(sex);
        sql_op.append("\"");
    }else if(age!=""){
        sql_op.append("age=");
        sql_op.append(age);
    }else if(tel!=""){
        sql_op.append("tel=\"");
        sql_op.append(tel);
        sql_op.append("\"");
    }else if(school!=""){
        sql_op.append("school=\"");                                             
        sql_op.append(school);
        sql_op.append("\"");
    }else if(id!=""){
        sql_op.append("id=");
        sql_op.append(id);
    }else{                                                                      
        sql_op="select * from students";
    }  
//  std::cout<<sql_op<<std::endl;
    if(_sql_op(sql_op)){
        return _select_data();
    }  
}   
       
bool mysql_api::mysql_insert(std::string name,std::string sex,std::string age,std::string tel=NULL,std::string school=NULL)
{   
    //insert [into] 表名 [(列名1, 列名2, 列名3, ...)] values (值1, 值2, 值3, ...);
    //insert into students values(NULL, "王刚", "男", 20, "13811371377",NULL);
    std::string sql_op;
    sql_op="insert into students (name,sex,age,tel,school) values (\"";
    sql_op.append(name);                                                        
    sql_op.append("\",\"");
    sql_op.append(sex);
    sql_op.append("\",");
    sql_op.append(age);
    sql_op.append(",\"");
    sql_op.append(tel);
    sql_op.append("\",\"");
    sql_op.append(school);
    sql_op.append("\")");
//  std::cout<<sql_op<<std::endl;
    return _sql_op(sql_op);
}   
    
bool mysql_api::mysql_delete(std::string id,std::string name,std::string sex,std::string age,std::string tel,std::string school)
{   
    //delete from 表名称 where 删除条件
    //删除表中的所有数据: delete from students;
    std::string sql_op="delete from students where ";
    if(name!=""){
        sql_op.append("name=\"");
        sql_op.append(name);
        sql_op.append("\"");
    }else if(sex!=""){
        sql_op.append("sex=\"");
        sql_op.append(sex);
        sql_op.append("\"");
    }else if(age!=""){
        sql_op.append("age=");
        sql_op.append(age);
    }else if(tel!=""){
        sql_op.append("tel=\"");
        sql_op.append("\"");
        sql_op.append(tel);
    }else if(school!=""){
        sql_op.append("school=\"");
        sql_op.append(school);
        sql_op.append("\"");
    }else if(id!=""){
        sql_op.append("id=");
        sql_op.append(id);
    }
//  std::cout<<sql_op<<std::endl;
    if(sql_op=="delete from students where ")
        return false;
    return _sql_op(sql_op);
}   
    
bool mysql_api::mysql_updata(std::string oldname,std::string newname,std::string oldsex,std::string newsex,            std::string oldage,std::string newage,std::string oldtel,std::string newtel,std::string oldschool,std::string newschool)
{   
    //update 表名称 set 列名称=新值 where 更新条件;
    // update students set age=19,tel="18829342744" where tel="6703" and school="xpu";                                                
    std::string sql_op;
    std::string where;
    bool ret=false; 
    sql_op="update students set " ;
    where="where ";
    if(oldname!=""){
        where.append("name=\"");
        where.append(oldname);
        where.append("\"");
    }  
    if(newname!=""){
        sql_op.append("name=\"");
        sql_op.append(newname);
        sql_op.append("\"");
    }
    if(oldsex!=""){
        if(where!="where ")
            where.append(" and ");
        where.append("sex=\"");
        where.append(oldsex);
        where.append("\"");
    }
    if(newsex!=""){
        sql_op.append("sex=\"");
        sql_op.append(newsex);
        sql_op.append("\"");
    }
    if(oldage!=""){
        if(where!="where ")
            where.append(" and ");                                                                                                    
        where.append("age=");
        where.append(oldage);
    }
    if(newage!=""){
        sql_op.append("age=");
        sql_op.append(newage);
    }
    if(oldtel!=""){
        if(where!="where ")
            where.append(" and ");
        where.append("tel=\"");
        where.append(oldtel);
        where.append("\"");
    }
    if(newtel!=""){
        sql_op.append("tel=\"");
        sql_op.append(newtel);
        sql_op.append("\"");                                                                                                          
    }
    if(oldschool!=""){
        if(where!="where ")
            where.append(" and ");
        where.append("school=\"");
        where.append(oldschool);
        where.append("\"");
    }
    if(newschool!=""){
        sql_op.append("school=\"");
        sql_op.append(newschool);
        sql_op.append("\"");
    }
    sql_op.append(" ");
    
    std::string res=sql_op+where;
//  std::cout<<res<<std::endl;
    return _sql_op(res);
}   
        
bool mysql_api::mysql_close_sql()
{   
    //关闭与MySQL服务器的连接
    mysql_close(&mysql);
}   
    
mysql_api::~mysql_api()
{   
}   
    
bool mysql_api::_sql_op(std::string &sql_op)
{   
//  std::cout<<sql_op<<std::endl;
    bool ret=false;
    if(mysql_query(&mysql,sql_op.c_str())==0){
        ret=true;
//      std::cout<<ret<<std::endl;
    }
    return ret;
}   
    
bool mysql_api::_select_data()
{   
    MYSQL_RES *ret=mysql_store_result(&mysql);
    MYSQL_ROW row;
    int num_fields=mysql_num_fields(ret);
    std::cout<<"HTTP/1.1 200 OK\r\n\r\n";
    std::cout<<"<html>"<<std::endl;
    std::cout<<"<head>"<<std::endl;
    std::cout<<"<h1>id  name    sex   age   tel     school";                    
    std::cout<<"</h1>"<<std::endl;
    while ((row = mysql_fetch_row(ret)))
    {
        unsigned long *lengths;
        lengths = mysql_fetch_lengths(ret);
        std::cout<<"<h2>";
        for(int i = 0; i < num_fields; i++)
        {
            printf("[%.*s] ", (int)lengths[i], row[i] ? row[i] : "NULL");
        }
        std::cout<<"</h2>"<<std::endl;
        std::cout<<std::endl;
    }   
    std::cout<<"</head>"<<std::endl;
    std::cout<<"</html>"<<std::endl;                                            
    mysql_free_result(ret);
    return true;
}

htdocs/mysql_connect/Makefile:

ROOT_PATH=$(shell pwd)#shell是函数,它的参数是操作系统shell的命令,它和反引号的>功能是相同的,这就是说shell函数把执行操作系统命令后的输出作为函数返回值,这个函>数会生成一个shell程序来执行命令,所以要注意运行性能
                                                                                
#LINK=-I/home/chehlling/httpd/mysql_connect/mysql-clib/include     -L/home/chehlling/httpd/mysql_connect/mysql-clib/lib -lmysqlclient -lpthread -lm -lrt -ldl
 
sql_api:main.cpp sql_api.cpp
    g++ -o [email protected] $^ `${ROOT_PATH}/mysql-clib/bin/mysql_config --cflags --libs ` -lstdc++ 
 
.PHONY:clean
clean:
    rm -f sql_api
 
.PHONY:output
output:sql_api
    cp -f sql_api ../../output/htdocs/cgi_mysql/

htdocs/index.html:(大数运算操作)

<html>  
    <head>
        <h1>hello chehlling</h1>
    </head>
    <body>
        <hr/>
        <form action="cgi_bin/math_cgi" method="POST">
            data1: <input type="text" name="data1"/><br/>
            data2: <input type="text" name="data2"/><br/>
            +: <input type="radio" name="op" value="ADD"><br/>
            -: <input type="radio" name="op" value="SUB"><br/>
            *: <input type="radio" name="op" value="MUL"><br/>
            /: <input type="radio" name="op" value="DIV"><br/>
            %: <input type="radio" name="op" value="MOD"><br/>                  
            <input type="submit" /><br/>
        </form>
        <hr/>
        
        <img src="20.jpg" alt="mantouheqi" dth="200" height="300"/>
    </body>
</html>

htdocs/cgi_bin/math_cgi.cpp:

#include "bigdata.h"
#include <iostream>
#include <string>                                                               
#include <stdio.h>
#include <errno.h>
#include <vector>
#include <stdlib.h>
#include <string.h>
#define _SIZE_ 2048
 
void get_args(std::vector<std::string> &vec)
{
    std::string method=getenv("METHOD");
    std::string query_string; 
    std::string content_length;
    char ch=‘a‘;
    int index=0;
    int ret=-1;
    char buf[_SIZE_];
    memset(buf,‘\0‘,sizeof(buf));
    if(method=="POST"){//POST
        std::string content_length=getenv("CONTENT_LENGTH");
        int len=atoi(content_length.c_str());
        memset(buf,‘\0‘,sizeof(buf));
        while(len){//&& index<sizeof(buf)-1){
            ret=read(0,&ch,1);
            buf[index++]=ch;
            len--;
        }
        if(len!=0){
            printf("error!\n");
            return;
        }
    }else{//GET
        query_string=getenv("QUERY_STRING");
        strcpy(buf,query_string.c_str());
        index=query_string.size();
    }
    buf[index]=‘\0‘;
//  std::cout<<buf<<std::endl;
    int countin=0;
    char *end=buf+index;
    while(end!=buf){
        if(*end == ‘=‘){
            vec.push_back(end+1);
        //  std::cout<<vec[countin++]<<std::endl;
        }
        if(*end == ‘&‘){
            *end=‘\0‘;
        }
        end--;                                                                  
    }
}   

void echo_result(std::vector<std::string> &vec)
{
    const char *op=vec[0].c_str();
    BigData data1(vec[2].c_str());
    BigData data2(vec[1].c_str());
//  std::cout<<data1<<"     "<<data2<<std::endl;
    BigData sum;
    char ch;
    if( strcmp("ADD",op)==0 ){
        sum=data1+data2;
        ch=‘+‘;
    }else if( strcmp("SUB",op)==0 ){
        sum=data1-data2;
        ch=‘-‘;
    }else if( strcmp("MUL",op)==0 ){
        sum=data1*data2;
        ch=‘*‘;
    }else if( strcmp("DIV",op)==0 ){
        sum=data1/data2;
        ch=‘/‘;
    }else if( strcmp("MOD",op)==0 ){
        sum=data1%data2;
        ch=‘%‘;
    }else{
        return;
    }
    std::cout<<"HTTP/1.1 200 OK\r\n\r\n";
    std::cout<<"<html>"<<std::endl;                                             
    std::cout<<"<head>"<<std::endl;
    std::cout<<"  ";
    std::cout<<"<h1>math_cgi     ";
    std::cout<<op <<"</h1>"<<std::endl;
    std::cout<<"</head>"<<std::endl;
    std::cout<<"<body>"<<std::endl;
    std::cout<<data1<<ch<<data2<<"="<<sum<<std::endl;
    std::cout<<"</body>"<<std::endl;
    std::cout<<"</html>"<<std::endl;
     
}    
int main(int argc,char *argv[])
{    
    std::vector<std::string> vec;                                               
    get_args(vec);//reverse store args
    echo_result(vec);
     
    return 0;
}

htdocs/cgi_bin/bigadata.h:

#ifndef BIG_DATA_H
#define BIG_DATA_H
#include <string>
#include <string.h>                                                             
#include <iostream>
#include <cassert>
 
#define UN_INIT 0xccccccccccccccccll
#define MAX_INT64 0x7fffffffffffffffll
#define MIN_INT64 0x8000000000000000ll
 
typedef long long INT64;
 
class BigData
{
public:
    BigData(INT64 data = UN_INIT);
    BigData(const char *pData);
    BigData operator+(BigData& bigData);
    BigData operator-(const BigData& bigData);
    BigData operator*(const BigData& bigData);
    BigData operator/(const BigData& bigData);
    BigData operator%(const BigData& bigData);
    //=======================================
    bool operator<(const BigData& bigData);
    bool operator>(const BigData& bigData);
    bool operator==(const BigData& bigData);
    
    std::ostream& operator<<(std::ostream& _cout);
    
    friend std::ostream& operator<<(std::ostream& _cout, const BigData& bigData);
    friend std::istream& operator>>(std::istream& _cin, BigData bigData);  
private:
    std::string Add(std::string left, std::string right);
    std::string Sub(std::string left, std::string right);
    std::string Mul(std::string left, std::string right);
    std::string Div(std::string left, std::string right);
    void INT64ToString();
    bool IsINT64Owerflow()const;
    bool IsLeftStrBig(char *pLeft, size_t LSize, char *pRight, size_t RSize);
    char SubLoop(char *pLeft, size_t LSize, char *pRight, size_t RSize);
    
private:                                                                    
    long long m_llValue;
    std::string m_strData;
};  
#endif

htdocs/cgi_bin/bigadata.cpp:

htdocs/cgi_bin/Makefile:

math_cgi:math_cgi.cpp bigdata.cpp
    g++ -o [email protected] $^ -lstdc++
                                                                                
.PHONY:clean
clean:
    rm -rf math_cgi
   
.PHONY:output
output:math_cgi
    cp -f math_cgi ../../output/htdocs/cgi_bin/

httpd.c  httpd.h   main.c  这三个文件和上一篇一样

Makefile

ROOT_PATH=$(shell pwd)
LDFLAGS=-lpthread
FLAGS=#-D_DEBUG_#-g
 
CC=gcc
BIN=httpd
SRC=$(shell ls *.c)
OBJ=$(SRC:.c=.o)
                                                                                
CGI_BIN=htdocs/cgi_bin
MYSQL_CONNECT=htdocs/mysql_connect
 
.PHONY:all
all:$(BIN) cgi
$(BIN):$(OBJ)
    @echo "Linking [$^] to [[email protected]]"
    @$(CC) -o [email protected] $^  $(LDFLAGS)
    @echo "Linking done..."
%.o:%.c
    @echo "Compling [$<] to [[email protected]]"
    @$(CC) -c $< -D_V2_ $(FLAGS) 
    @echo "Compling done..."
   
   
.PHONY:cgi
cgi:
    @for name in `echo $(CGI_BIN)`;    do        cd $$name;        make;        cd -;    done
    @for name in `echo $(MYSQL_CONNECT)`;    do        cd $$name;        make;        cd -;    done
   
.PHONY:clean
clean:
    @rm -rf *.o $(BIN) output
    @for name in `echo $(CGI_BIN)`;    do        cd $$name;        make clean;        cd -;    done
    @for name in `echo $(MYSQL_CONNECT)`;    do        cd $$name;        make clean;        cd -;    done
.PHONY:output
output:$(BIN) cgi
    @mkdir -p output/log
    @cp -rf htdocs output/
    @mkdir -p output/htdocs/cgi_bin
    @cp -f httpd output/
    @cp -f start.sh output/
    @cp -rf conf output/
    @mkdir -p output/htdocs/cgi_mysql
    @for name in `echo $(CGI_BIN)`;\                             &n

以上是关于HTTP服务器加强版的主要内容,如果未能解决你的问题,请参考以下文章

Spark 加强版WordCount ,统计日志中文件访问数量

二柱子课后题加强版的加强版

bzoj2594: [Wc2006]水管局长数据加强版

HDU 4578 - Transformation - [加强版线段树]

自定义View——加强版的EditText

bzoj3514: Codechef MARCH14 GERALD07加强版