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 ,统计日志中文件访问数量