├── .github └── workflows │ └── test.yml ├── .gitignore ├── LICENSE ├── README.en.md ├── README.md ├── config.json ├── doc ├── DealHttp.en.md ├── DealHttp.md ├── HttpServer.en.md ├── HttpServer.md ├── configjson.cn.md ├── configjson.md ├── framework.cn.md ├── framework.md ├── others.md ├── serverbuild.cn.md └── serverbuild.md ├── index.html ├── install.sh ├── logo.png ├── makefile ├── makefile.win ├── old ├── README.md ├── class │ ├── Server.cpp │ ├── guard.cpp │ ├── ini.h │ ├── memory.h │ ├── poll.cpp │ ├── sqlInstall.sh │ ├── threadPool.cpp │ └── webtoken.cpp ├── cpp │ ├── guardAll.cpp │ ├── guardHttp.cpp │ ├── http.cpp │ ├── init.cpp │ ├── mainold.cpp │ ├── my.ini │ ├── server.cpp │ └── thread.cpp ├── cppweblinux.h ├── hpp │ ├── http.h │ ├── server.h │ └── thread.h ├── lib │ ├── http.h │ ├── libhttp.a │ ├── libserver.a │ ├── libsql.a │ ├── libthreadpoll.a │ ├── libthreadpool.a │ ├── server.h │ └── thread.h └── res │ ├── 404.html │ ├── favicon.ico │ ├── index.html │ └── ini.html ├── src ├── .clang-tidy ├── cpp │ ├── dealask.cpp │ ├── main.cpp │ ├── mainold.cpp │ ├── redis.cpp │ └── sql.cpp ├── example │ ├── README.md │ ├── api-req │ │ ├── config.h │ │ ├── config.json │ │ ├── main.cpp │ │ └── makefile │ ├── chat-axios │ │ ├── main.cpp │ │ └── makefile │ ├── cli-ask │ │ ├── dict.cpp │ │ ├── main.cpp │ │ └── makefile │ ├── composite-route │ │ ├── main.cpp │ │ └── makefile │ ├── delete-path │ │ ├── index.html │ │ ├── main.cpp │ │ ├── makefile │ │ └── test │ │ │ └── index.html │ ├── easy-http-server │ │ ├── index.html │ │ ├── main.cpp │ │ └── makefile │ ├── gram-redirect │ │ ├── main.cpp │ │ └── makefile │ ├── log-setting │ │ ├── index.html │ │ ├── main.cpp │ │ └── makefile │ ├── middleware-use │ │ ├── index.html │ │ ├── main.cpp │ │ └── makefile │ ├── old-version │ │ ├── index.html │ │ ├── main.cpp │ │ └── makefile │ ├── online-disk │ │ ├── config.h │ │ ├── config.json │ │ ├── edit.html │ │ ├── index.html │ │ ├── jump.html │ │ ├── login.html │ │ ├── main.cpp │ │ ├── makefile │ │ ├── route.h │ │ ├── template │ │ │ └── readme.html │ │ └── text.txt │ ├── ranking-list │ │ ├── api.html │ │ ├── main.cpp │ │ └── makefile │ ├── redirect-gram │ │ ├── main.cpp │ │ └── makefile │ ├── render-html │ │ ├── main.cpp │ │ ├── makefile │ │ └── test.html │ ├── request-struct │ │ ├── api.html │ │ ├── main.cpp │ │ └── makefile │ ├── route-use │ │ ├── index.html │ │ ├── main.cpp │ │ └── makefile │ ├── set-cookie │ │ ├── main.cpp │ │ └── makefile │ ├── ssl-https │ │ ├── cacert.pem │ │ ├── cert.csr │ │ ├── index.html │ │ ├── main.cpp │ │ ├── makefile │ │ ├── privkey.pem │ │ └── step.md │ ├── static-file │ │ ├── index.html │ │ ├── main.cpp │ │ ├── makefile │ │ └── temp │ │ │ └── index.html │ ├── thread-model │ │ ├── index.html │ │ ├── main.cpp │ │ └── makefile │ ├── upload-file │ │ ├── index.html │ │ ├── main.cpp │ │ └── makefile │ └── use-cppweb │ │ ├── index.html │ │ ├── main.cpp │ │ └── makefile ├── hpp │ ├── argc.h │ ├── config.h │ ├── cppweb.h │ ├── dealask.h │ ├── email.h │ ├── encrypt.h │ ├── proxy.h │ ├── route.h │ ├── serverpool.cpp │ └── sql.h └── test │ ├── arg_test.cpp │ ├── base64_test.cpp │ ├── cli_test.cpp │ ├── client_test.h │ ├── complete_test.cpp │ ├── config_test.ini │ ├── dealhttp_test.h │ ├── ini_test.cpp │ ├── log_test.cpp │ ├── main.cpp │ ├── makefile │ ├── onlinetest.h │ ├── regex_test.cpp │ └── test.h └── ssl ├── cacert.pem └── privkey.pem /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: 4 | push: 5 | branches: 6 | - refactor/c2cpp 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-20.04 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v3 14 | - name: Install build tools 15 | run: | 16 | sudo apt-get update 17 | sudo apt-get install -y build-essential curl libssl-dev 18 | - name: Run test 19 | run: | 20 | cd src/test 21 | make 22 | ./main 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | *.out 3 | *.exe 4 | main 5 | main_ssl 6 | *.zip 7 | *.vim 8 | *.pid 9 | *.log 10 | build 11 | CMakeLists.txt 12 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | //this file config the server 3 | //change server by change this file 4 | //set the bound port 5 | "port":5200, 6 | //default file when ask / 7 | "default file":"index.html", 8 | //if fork model,use "MULTIPLEXING" or "FORK" or"THREAD" or "REACTOR" 9 | "model":"REACTOR", 10 | //if long connect 11 | "long connect":true, 12 | //if run in background 13 | "background":false, 14 | //if use guard 15 | "guard":false, 16 | //if open the log 17 | "logger":true, 18 | //log path 19 | "log path":"./access.log", 20 | //auto find the file 21 | "auto":true, 22 | //message print to stdout or not 23 | "message print":true, 24 | //forward proxy,only be useful if model is fork or thread 25 | "forward proxy":false, 26 | //301 redirect,the arr must is a objext and have path and redirect,use as this 27 | // "redirect":[ 28 | // {"path":"/root","redirect":"./template"}, 29 | // {"path":"/temp","redirect":"./tem"} 30 | // ], 31 | "redirect":[], 32 | //remove path array 33 | //"delete path":["./template"], 34 | "delete path":[], 35 | //replace the path,the arr must is a objext and have path and replace 36 | // "replace":[ 37 | // {"path":"/root","replace":"./template"}, 38 | // {"path":"/temp","replace":"./tem"} 39 | // ], 40 | "replace":[], 41 | //set agent array 42 | // "reverse proxy":[ 43 | // {"model":"RANDOM","path":"/try*","host":["127.0.0.1:5201","127.0.0.1:5202"],"weight":[1,3]} 44 | // ], 45 | "ssl config":{ 46 | "reverse proxy":[], 47 | //https certificate path 48 | "cert path":"./ssl/cacert.pem", 49 | "cert password":"123456", 50 | "key path":"./ssl/privkey.pem" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /doc/DealHttp.md: -------------------------------------------------------------------------------- 1 | ## 本文目的 2 | 3 | - 介绍DealHttp用法 4 | - 这是重点**类**,学习完这个和HttpServer类之后就可以创作了 5 | 6 | ## 类定义类型 7 | 8 | ### FileKind 9 | 10 | ``` 11 | enum FileKind{ 12 | UNKNOWN=0,HTML=1,TXT=2,IMAGE=3,NOFOUND=4,CSS=5,JS=6,ZIP=7,JSON=8, 13 | }; 14 | ``` 15 | 16 | - 文件的类型 ,报文的类型 17 | - UNKNOWN表示未知类型但是也可以生成报文 18 | - NOFOUND会发送404报文 19 | 20 | ### Status 21 | 22 | ```cpp 23 |     enum Status{ 24 | STATUSOK=200,STATUSNOCON=204,STATUSMOVED=301,STATUSBADREQUEST=400,STATUSFORBIDDEN=403, 25 | STATUSNOFOUND=404,STATUSNOIMPLEMENT=501, 26 | }; 27 | ``` 28 | 29 | - http状态码 30 | 31 | ### Datagram 32 | 33 | ```cpp 34 | struct Datagram{ 35 | Status statusCode; 36 | FileKind typeFile; 37 | unsigned fileLen; 38 | std::unordered_map head; 39 | std::unordered_map cookie; 40 | std::string typeName; 41 | std::string body; 42 | Datagram():statusCode(STATUSOK),typeFile(TXT),fileLen(0){}; 43 | }; 44 | ``` 45 | 46 | - 响应报文的结构体 47 | 48 | - typename自定义类型,一般不用 49 | 50 | #### Datagarm 函数 51 | 52 | ##### 报文函数 53 | 54 | ```cpp 55 | inline void json(Status staCode,const std::string& data) 56 | inline void html(Status staCode,const std::string& data) 57 | inline void js(Status staCode,const std::string& data) 58 | inline void css(Status staCode,const std::string& data) 59 | inline void txt(Status staCode,const std::string& data) 60 | inline void image(Status staCode,const std::string& data) 61 | inline void file(Status staCode,const std::string& data) 62 | ``` 63 | 64 | - 参数,状态码以及数据 65 | 66 | - 函数会生成对应的http报文数据 67 | 68 | ##### 状态函数 69 | 70 | ```cpp 71 | inline void noFound() 72 | inline void forbidden() 73 | void redirect(const std::string& location,bool forever=false) 74 | ``` 75 | 76 | - 对应404,403以及重定向报文 77 | 78 | ### Request 79 | 80 | ```cpp 81 | class Request{ 82 | public: 83 | std::string method; 84 | std::string askPath; 85 | std::string version; 86 | std::unordered_map head; 87 | const char* body; 88 | const char* error; 89 | bool isFull;//judge if the request be analyse 90 | } 91 | ``` 92 | 93 | - 请求报文结构体 94 | 95 | #### request函数 96 | 97 | ##### analysisRequest 98 | 99 | ```cpp 100 | bool analysisRequest(const void* recvText,bool onlyTop=false) 101 | ``` 102 | 103 | - 解析请求报文,第一个参数为报文,返回是否成功 104 | 105 | - recvText一般传入http.info.recvText 106 | 107 | - request其他函数都需要先经历这个函数解析 108 | 109 | ##### getWildUrl 110 | 111 | ```cpp 112 | std::string getWildUrl(const char* route,void* recvMsg=NULL) 113 | ``` 114 | 115 | - 获取路由中携带的后续信息 116 | 117 | - 第一个是路由,第二个是报文,如果已经解析可设置为空 118 | 119 | - 返回结果 120 | 121 | ##### routePairing 122 | 123 | ```cpp 124 | bool routePairing(std::string key,std::unordered_map& pairMap,const char* recvText=NULL) 125 | ``` 126 | 127 | - 路由匹配 128 | 129 | - 详情可见exanple 130 | 131 | ##### formvalue 132 | 133 | ```cpp 134 | std::string formValue(const std::string& key,void* buffer=NULL) 135 | ``` 136 | 137 | - 获取post报文中的表单值 138 | 139 | ##### routeValue 140 | 141 | ```cpp 142 | std::string routeValue(const std::string& key,void* buffer=NULL) 143 | ``` 144 | 145 | - 获取路由中的key Value 146 | 147 | ##### createAskRequest 148 | 149 | ```cpp 150 | bool createAskRequest(void* buffer,unsigned buffLen) 151 | ``` 152 | 153 | - 创建请求报文 154 | 155 | - 一般客户端用 156 | 157 | ## 函数介绍 158 | 159 | ### analysisHttpAsk 160 | 161 | ```cpp 162 | const char* analysisHttpAsk(void* pask,const char* pneed="GET",int needLen=3); 163 | ``` 164 | 165 | - 获取路由值 166 | - 在2.0很少用,一般在1.0需要手动获取 167 | 168 | ### findBackString 169 | 170 | ``` 171 | char* findBackString(char* local,int len,char* word,int maxWordLen); 172 | const char* findBackString(char* local,int len,std::string& buffer) 173 | ``` 174 | 175 | - 获得指定字符串后面的字符串 176 | - 第一参数是匹配字符串 177 | - 第二参数是匹配的长度 178 | - 第三参数是后面字符串缓冲区 179 | - 第四是缓冲区长度 180 | - 返回值是字符串首地址 181 | - 2.0很少用 182 | 183 | ### createTop 184 | 185 | ``` 186 | void createTop(FileKind kind,char* ptop,int* topLen,int fileLen); 187 | ``` 188 | 189 | - 2.0很少用,创建报文头,一般直接createsendmeg 190 | 191 | ### createSendMsg 192 | 193 | ``` 194 | bool createSendMsg(FileKind kind,char* buffer,const char* pfile,int* plong) 195 | ``` 196 | 197 | - 创建报文,第一个参数是报文类型,如果没有 请注册选择unknow,如果发送404选择nofound,第二个参数是报文缓冲区,第三个参数是报文主体的文件名(主体需先写入一个文件) 198 | 第四个参数是指针接受报文的长度 199 | - 返回值是创建是否成功 200 | 201 | ### autoAnalysisGet 202 | 203 | ``` 204 | int autoAnalysisGet(const char* message,char* psend,const char* pfirstFile,int* plen); 205 | ``` 206 | 207 | - 在2.0不需要自己调用,是自动分析get请求生成报文函数 208 | - 返回值是2表示文件找不到,0表示函数失败,1表示成功 209 | 210 | ### getKeyValue 211 | 212 | ``` 213 | const char* getKeyValue(const void* message,const char* key,char* value,int maxValueLen); 214 | ``` 215 | 216 | - 获取键值对,返回指向值指针 217 | - 第一个参数是报文内容,第二个是键,第三个是只缓冲区,第四个是缓冲区长度 218 | 219 | ### getKeyLine 220 | 221 | ``` 222 | const char* getKeyLine(const void* message,const char* key,char* line,int maxLineLen); 223 | ``` 224 | 225 | - 和上一个函数类似,不过是返回一行内容 226 | 227 | ### getAskRoute 228 | 229 | ``` 230 | const char* getAskRoute(const void* message,const char* askWay,char* buffer,unsigned int bufferLen); 231 | ``` 232 | 233 | - 个人尽量不要调用是一个内部调用函数 234 | 235 | ### getRouteValue 236 | 237 | ``` 238 | const char* getRouteValue(const void* routeMeg,const char* key,char* value,unsigned int valueLen); 239 | ``` 240 | 241 | - 获取get请求路由中的键值对 242 | - 第一个参数是路由信息,第二个是键,第三个是值缓冲区,第四个是长度 243 | - 返回值指向值,如果找不到返回null 244 | 245 | ### getWildUrl 246 | 247 | ``` 248 | const char* getWildUrl(const void* getText,const char* route,char* buffer,int maxLen) 249 | ``` 250 | 251 | - 获取路由中携带的后续信息 252 | - 第一个是报文,第二个注册的路由,第三个是缓冲区,第四个缓冲区大小 253 | - 返回值指向缓冲区,失败返回null 254 | 255 | ### getRecFile 256 | 257 | ``` 258 | int getRecFile(const void* message,char* fileName,int nameLen,char* buffer,int bufferLen); 259 | ``` 260 | 261 | - 从报文中获取上传文件的内容 262 | - 263 | 264 | ### dealUrl 265 | 266 | ``` 267 | static void dealUrl(const char* url,char* urlTop,char* urlEnd); 268 | ``` 269 | 270 | - 处理url的静态函数,top返回url包含的域名,end.返回附加信息 271 | - 一般不会调用 272 | 273 | ### customizeAddTop 274 | 275 | ``` 276 | void* customizeAddTop(void* buffer,int bufferLen,int statusNum,int contentLen,const char* contentType="application/json",const char* connection="keep-alive"); 277 | ``` 278 | 279 | - 自己创建报文 280 | - 第一个函数是报文的缓冲区,第二个是缓冲区长度,第四个是状态码,第四个是报文主体的长度,第四个是内容默认是json,最后一个是连接状态默认长连接 281 | - 返回值是返回缓冲区头部 282 | 283 | ### customizeAddHead 284 | 285 | ``` 286 | void* customizeAddHead(void* buffer,int bufferLen,const char* key,const char* value); 287 | ``` 288 | 289 | - 加自定义的额外头部 290 | - 后两个参数是键值对 291 | 292 | ### customizeAddBody 293 | 294 | ``` 295 | int customizeAddBody(void* buffer,int bufferLen,const char* body,unsigned int bodyLen); 296 | ``` 297 | 298 | - 添加自定义的body部分 299 | - 返回值是报文总长度 300 | - 参数最后一个是body的长度 301 | 302 | ### urlDecode 303 | 304 | ``` 305 | static const char* urlDecode(char* srcString); 306 | ``` 307 | 308 | - 解决无法显示中文的问题 309 | - srcString是传入的字符串,会在源字符串上更改 310 | 311 | ### setCookie 312 | 313 | ``` 314 | bool setCookie(void* buffer,int bufferLen,const char* key,const char* value,int liveTime=-1,const char* path=NULL,const char* domain=NULL); 315 | ``` 316 | 317 | - 设置cookie,函数只能用于自定义报文使用 318 | - 参数是一个键值对,liveTime是cookie生效时间,负数表示关闭浏览器失效,正数表示秒数,0表示立刻失效 319 | - path和domain可以自己在网上查。。。 320 | 321 | ## 使用例子 322 | 323 | - 在example中有使用实例 324 | -------------------------------------------------------------------------------- /doc/HttpServer.en.md: -------------------------------------------------------------------------------- 1 | ## Purpose of this article 2 | 3 | - Introduce the functions and usage of the httpserver class 4 | 5 | ## class description 6 | 1. It is strongly recommended that you look at this class first. This is the 2.0 version of the server. Getting started is very simple. 7 | 8 | 2. This class private inherits ServerTcpIp, but you do not need to learn its parent class in advance 9 | 10 | ## class definition type 11 | 12 | ### RouteType 13 | 14 | ```cpp 15 | enum RouteType{//oneway stand for like /hahah,wild if /hahah/*,static is recource static 16 | ONEWAY,WILD,STATIC,STAWILD 17 | }; 18 | ``` 19 | - ONEWAY means single parsing, parsed as the message of the content 20 | 21 | - WILD means PAN parses all packets of this prefix 22 | 23 | - STATIC and STAWILD are the methods of internal calls, and external calls do not take effect 24 | 25 | > the struct is private 26 | 27 | ### AskType 28 | 29 | ```cpp 30 | enum AskType{//different ask ways in http 31 | GET,POST,PUT,DELETE,OPTIONS,CONNECT,ALL, 32 | }; 33 | ``` 34 | 35 | - Type of application message 36 | 37 | - GET is a get request, POST is a post request, ALL means all requests are registered, and so on 38 | 39 | ### RunModel 40 | 41 | ```cpp 42 | enum RunModel{//the server model of run 43 | FORK,MULTIPLEXING,THREAD,RECTOR 44 | }; 45 | ``` 46 | 47 | - The mode in which the server is running 48 | 49 | ## Function introduction 50 | 51 | ### Constructor 52 | 53 | ```cpp 54 | HttpServer(unsigned port, bool debug=false, RunModel serverModel=MULTIPLEXING, unsigned threadNum=5) 55 | :ServerTcpIp(port),model(serverModel) 56 | ``` 57 | 58 | - The first parameter is the port number to specify the binding 59 | 60 | - The second is whether the debug mode is turned on 61 | 62 | > Debug mode will output the content of the request and the result 63 | > Closed will not output (default closed) 64 | 65 | - The third is server mode 66 | 67 | - The fourth is the number of threads if multi-threaded 68 | 69 | ### clientOutHandle 70 | 71 | ```cpp 72 | bool clientOutHandle(void (*pfunc)(HttpServer&,int num,void* ip,int port)); 73 | ``` 74 | 75 | - This is the class that handles user disconnection (non-essential function) 76 | - Triggered every time user disconnects 77 | - pfunc is a callback function, the callback will pass *this through HttpServer, num pass socket, ip pass ip, port pass port 78 | - The function can only be called once, and the second call returns false 79 | 80 | ### clientInHandle 81 | 82 | ```cpp 83 | bool clientInHandle(void (*pfunc)(HttpServer&,int num,void* ip,int port)); 84 | ``` 85 | 86 | - Client connection trigger function 87 | - Similar to the previous function, so I won't go into details 88 | 89 | ### **routeHandle** 90 | 91 | ```cpp 92 | bool routeHandle(AskType ask,const char* route,void (*pfunc)(HttpServer&,DealHttp&,int) 93 | bool routeHandle(AskType ask,const char* route,const std::initializer_list& pfuncs)) 94 | ``` 95 | 96 | - Core function, providing callbacks for routing processing, the number is not limited 97 | - The first is the route registration type 98 | - The second parameter is the registered route 99 | - The third is the callback function 100 | - The callback function will pass in the Dealhttp object. Click [here](./DealHttp.md) for the introduction of this class. The first pass in *this, and the third pass in the socket corresponding to the request. After this function is called, it will automatically send buffer message 101 | - The return value indicates whether it was successful or not 102 | 103 | ### **run** 104 | 105 | ```cpp 106 | void run(const char* defaultFile=NULL) 107 | ``` 108 | 109 | - Core function, call this function to start the server 110 | - The first parameter is the default home page 111 | - This function **will not return** unless an error occurs 112 | 113 | ### httpSend 114 | 115 | ```cpp 116 | int httpSend(int num, void* buffer, int sendLen); 117 | ``` 118 | 119 | - Extra send function, generally not called unless additional data is sent 120 | - The first parameter is the value of the socket, the second is the send content buffer, and the third is the send length 121 | 122 | ### lastError 123 | 124 | ```cpp 125 | const char* lastError() 126 | ``` 127 | 128 | - get the last error 129 | 130 | ### disconnect 131 | 132 | ```cpp 133 | inline bool disconnect(int soc) 134 | ``` 135 | 136 | - Actively disconnect a client connection 137 | - parameter is socket client 138 | 139 | ### get post all 140 | 141 | ```cpp 142 | bool get(RouteType type,const char* route,void (*pfunc)(DealHttp&,HttpServer&,int,void*,int&)); 143 | bool post(RouteType type,const char* route,void (*pfunc)(DealHttp&,HttpServer&,int,void*,int&)); 144 | bool all(RouteType type,const char* route,void (*pfunc)(DealHttp&,HttpServer&,int,void*,int&)); 145 | inline bool get(const char* route,std::initializer_list pfuncs) 146 | ``` 147 | 148 | - The function is a simplified version of routehandle 149 | - the same except that the first parameter is automatically generated 150 | 151 | ### loadStatic 152 | 153 | ```cpp 154 | bool loadStatic(const char* route,const char* staticPath); 155 | ``` 156 | 157 | - Route path replacement, load static files 158 | 159 | - The first is the registered route, the second is the mapped path 160 | 161 | - also accepts * as a pan match 162 | 163 | ## Usage example 164 | 165 | - see HttpServer.cpp in the example 166 | 167 | ### deletePath 168 | 169 | ```cpp 170 | bool deletePath(const char* path); 171 | ``` 172 | 173 | - Set forbidden access paths 174 | - parameter is a forbidden path 175 | 176 | ### changeSetting 177 | 178 | ```cpp 179 | void changeSetting(bool debug,bool isLongCon,bool isAuto=true,unsigned maxSendLen=10,unsigned sslWriteTime=5,int recvWaitTime=3) 180 | ``` 181 | 182 | - Modify server configuration 183 | - One parameter is whether to enable debug mode 184 | - The second parameter is whether to use http long connection 185 | - The three parameters are automatically inferred routing files 186 | - Four parameters are the maximum memory usage, the default is 10M 187 | 188 | ### setMiddleware 189 | 190 | ```cpp 191 | bool setMiddleware(void (*pfunc)(HttpServer&,DealHttp&,int)) 192 | ``` 193 | 194 | - Set up middleware, the function will be called when there is a message 195 | 196 | ### continueNext 197 | 198 | ```cpp 199 | inline void continueNext(int cliSock) 200 | ``` 201 | 202 | - Continue execution after setting middleware 203 | 204 | ### setLog 205 | 206 | ```cpp 207 | bool setLog(void (*pfunc)(const void*,int),void (*errorFunc)(const void*,int)) 208 | ``` 209 | 210 | - Set the log, the first one is the access log 211 | 212 | - The second is the error log 213 | 214 | ### getCompleteMessage 215 | 216 | ```cpp 217 | int getCompleteMessage(int sockCli) 218 | ``` 219 | 220 | - Get the complete message 221 | 222 | ### changeSetting 223 | 224 | ```cpp 225 | void changeSetting(bool debug,bool isLongCon,bool isAuto=true,unsigned maxSendLen=1) 226 | ``` 227 | 228 | - Change the settings, the first is whether to debug mode, the second is whether to long link, the third is whether to enable the default path recognition, the fourth is the maximum size of the send buffer, the unit is **M** 229 | 230 | ### stopServer 231 | 232 | ```cpp 233 | inline void stopServer() 234 | ``` 235 | 236 | - stop the server from running 237 | - the run function will end 238 | 239 | #### resetServer 240 | 241 | ```cpp 242 | inline void resetServer() 243 | ``` 244 | 245 | - Clear all routing information 246 | -------------------------------------------------------------------------------- /doc/HttpServer.md: -------------------------------------------------------------------------------- 1 | ## 本文目的 2 | 3 | - 介绍httpserver类的函数和使用 4 | 5 | ## 类说明 6 | 1. 强烈建议您先看这个类这个是2.0版本的server,入门非常简单 7 | 8 | 2. 该类private继承ServerTcpIp,但您不需要提前学其父类 9 | 10 | ## 类定义类型 11 | 12 | ### RouteType 13 | 14 | ```cpp 15 | enum RouteType{//oneway stand for like /hahah,wild if /hahah/*,static is recource static 16 | ONEWAY,WILD,STATIC,STAWILD 17 | }; 18 | ``` 19 | - ONEWAY表示单解析 ,解析为该内容的报文 20 | 21 | - WILD 表示泛解析 解析该前缀所有报文 22 | 23 | - STATIC和STAWILD是内部调用的方式,外部调用不生效 24 | 25 | > 该结构体私有 26 | 27 | ### AskType 28 | 29 | ```cpp 30 | enum AskType{//different ask ways in http 31 | GET,POST,PUT,DELETE,OPTIONS,CONNECT,ALL, 32 | }; 33 | ``` 34 | 35 | - 申请报文的类型 36 | 37 | - GET为get请求 ,POST为post请求,ALL表示所有请求都注册,以此类推 38 | 39 | ### RunModel 40 | 41 | ```cpp 42 | enum RunModel{//the server model of run 43 | FORK,MULTIPLEXING,THREAD,RECTOR 44 | }; 45 | ``` 46 | 47 | - 服务器运行的模式 48 | 49 | ## 函数介绍 50 | 51 | ### 构造函数 52 | 53 | ```cpp 54 | HttpServer(unsigned port,bool debug=false,RunModel serverModel=MULTIPLEXING,unsigned threadNum=5) 55 | :ServerTcpIp(port),model(serverModel) 56 | ``` 57 | 58 | - 第一个参数是指定绑定的端口号 59 | 60 | - 第二个是调试模式是否开启 61 | 62 | > 调试模式会输出请求的内容和结果 63 | > 关闭者不会输出 (默认关闭) 64 | 65 | - 第三个是服务器模式 66 | 67 | - 第四个是如果多线程的话线程数量 68 | 69 | ### clientOutHandle 70 | 71 | ```cpp 72 | bool clientOutHandle(void (*pfunc)(HttpServer&,int num,void* ip,int port)); 73 | ``` 74 | 75 | - 这是处理用户断开连接的类 (非必要函数) 76 | - 每次用户断开会触发 77 | - pfunc是回调函数 ,回调会通过HttpServer传*this ,num传socket,ip传ip,port传端口 78 | - 函数只能调用一次 ,二次调用返回false 79 | 80 | ### clientInHandle 81 | 82 | ```cpp 83 | bool clientInHandle(void (*pfunc)(HttpServer&,int num,void* ip,int port)); 84 | ``` 85 | 86 | - 客户端连接触发函数 87 | - 和上一个函数类似,不做赘述 88 | 89 | ### **routeHandle** 90 | 91 | ```cpp 92 | bool routeHandle(AskType ask,const char* route,void (*pfunc)(HttpServer&,DealHttp&,int) 93 | bool routeHandle(AskType ask,const char* route,const std::initializer_list& pfuncs)) 94 | ``` 95 | 96 | - 核心函数 ,提供路由处理的回调 ,数量不限 97 | - 第一个是路由注册类型 98 | - 第二个参数是注册的路由 99 | - 第三个是回调函数 100 | - 回调函数会传入Dealhttp对象,该类介绍点击 [这里](./DealHttp.md), 第一个传入*this,第三个传入发起该请求对应的socket,该函数调用后会自动发送缓冲区报文 101 | - 返回值表示是否成功 102 | 103 | ### **run** 104 | 105 | ```cpp 106 | void run(const char* defaultFile=NULL) 107 | ``` 108 | 109 | - 核心函数,调用此函数服务器开始运行 110 | - 第一个参数是默认的网页首页 111 | - 该函数**不会返回**,除非出错 112 | 113 | ### httpSend 114 | 115 | ```cpp 116 | int httpSend(int num,void* buffer,int sendLen); 117 | ``` 118 | 119 | - 额外的发送函数 ,一般不会调用,除非有额外数据发送 120 | - 第一个参数为socket的值 ,第二个为发送内容缓冲区 ,第三个为发送长度 121 | 122 | ### lastError 123 | 124 | ```cpp 125 | const char* lastError() 126 | ``` 127 | 128 | - 获取上一次的错误 129 | 130 | ### disconnect 131 | 132 | ```cpp 133 | inline bool disconnect(int soc) 134 | ``` 135 | 136 | - 主动断开某个客户端连接 137 | - 参数为socket客户端 138 | 139 | ### get post all 140 | 141 | ```cpp 142 | bool get(RouteType type,const char* route,void (*pfunc)(DealHttp&,HttpServer&,int,void*,int&)); 143 | bool post(RouteType type,const char* route,void (*pfunc)(DealHttp&,HttpServer&,int,void*,int&)); 144 | bool all(RouteType type,const char* route,void (*pfunc)(DealHttp&,HttpServer&,int,void*,int&)); 145 | inline bool get(const char* route,std::initializer_list pfuncs) 146 | ``` 147 | 148 | - 函数是routehandle的简化版 149 | - 除了自动生成第一个参数外其他是一样的 150 | 151 | ### loadStatic 152 | 153 | ```cpp 154 | bool loadStatic(const char* route,const char* staticPath); 155 | ``` 156 | 157 | - 路由路径替换,加载静态文件 158 | 159 | - 第一个是注册的路由,第二个是映射的路径 160 | 161 | - 同样接受*作为泛匹配 162 | 163 | ## 使用例子 164 | 165 | - 见example内的HttpServer.cpp 166 | 167 | ### deletePath 168 | 169 | ```cpp 170 | bool deletePath(const char* path); 171 | ``` 172 | 173 | - 设置禁止访问的路径 174 | - 参数为禁止的路径 175 | 176 | ### changeSetting 177 | 178 | ```cpp 179 | void changeSetting(bool debug,bool isLongCon,bool isAuto=true,unsigned maxSendLen=10,unsigned sslWriteTime=5,int recvWaitTime=3) 180 | ``` 181 | 182 | - 修改server配置 183 | - 一参为是否开启调试模式 184 | - 二参为是否使用http长连接 185 | - 三参为自动推断路由文件 186 | - 四参为最大内存占用,默认为10M 187 | 188 | ### setMiddleware 189 | 190 | ```cpp 191 | bool setMiddleware(void (*pfunc)(HttpServer&,DealHttp&,int)) 192 | ``` 193 | 194 | - 设置中间件,在有报文会调用该函数 195 | 196 | ### continueNext 197 | 198 | ```cpp 199 | inline void continueNext(int cliSock) 200 | ``` 201 | 202 | - 设置中间件之后继续执行 203 | 204 | ### setLog 205 | 206 | ```cpp 207 | bool setLog(void (*pfunc)(const void*,int),void (*errorFunc)(const void*,int)) 208 | ``` 209 | 210 | - 设置日志,第一个是访问日志 211 | 212 | - 第二个是错误日志 213 | 214 | ### getCompleteMessage 215 | 216 | ```cpp 217 | int getCompleteMessage(int sockCli) 218 | ``` 219 | 220 | - 获取完整报文 221 | 222 | ### changeSetting 223 | 224 | ```cpp 225 | void changeSetting(bool debug,bool isLongCon,bool isAuto=true,unsigned maxSendLen=1) 226 | ``` 227 | 228 | - 改变设置,第一个是是否调试模式,第二个是是否长链接,第三个是是否开启路径默认识别,第四个是发送缓冲区最大大小,单位为**M** 229 | 230 | ### stopServer 231 | 232 | ```cpp 233 | inline void stopServer() 234 | ``` 235 | 236 | - 停止服务器运行 237 | - run函数会结束 238 | 239 | #### resetServer 240 | 241 | ```cpp 242 | inline void resetServer() 243 | ``` 244 | 245 | - 清除所有路由信息 246 | -------------------------------------------------------------------------------- /doc/configjson.cn.md: -------------------------------------------------------------------------------- 1 | ## 配置文件说明 2 | 3 | - 服务器通过读取config.json配置文件运行,请确保服务器目录有此文件 4 | 5 | - 配置文件config.json使用json格式支持//和/**/作为注释 6 | 7 | ### port 8 | 9 | - 绑定的端口 10 | 11 | - 若为0则随即绑定 12 | 13 | ### defalut file 14 | 15 | - 默认访问的html文件 16 | - 如果不想设置可为"" 17 | 18 | ### model 19 | 20 | - 服务器运行模式 21 | 22 | - 只能为"MULTIPLEXING" or "FORK" or"THREAD" or "REACTOR" 23 | 24 | ### long connect 25 | 26 | - bool类型,是否开启长连接 27 | 28 | ### background 29 | 30 | - bool类型,是否运行在后台 31 | 32 | ### guard 33 | 34 | - 是否开启宕机自动重启 35 | 36 | ### logger 37 | 38 | - 是否开启日志 39 | 40 | ### log path 41 | 42 | - 日志储存路径 43 | 44 | ### auto 45 | 46 | - 是否开启路径自动识别 47 | 48 | ### message print 49 | 50 | - bool类型,是否把输出打印到终端 51 | 52 | ### rediect 53 | 54 | - 重定向,结构为数组 55 | 56 | ```json 57 | "rediect":[ 58 | {"path":"/root","redirect":"https://baidu.com"}, 59 | {"path":"/temp","redirect":"./tem"} 60 | ], 61 | ``` 62 | 63 | ### delete path 64 | 65 | - 手动排除路径 66 | 67 | - 为字符串数组 68 | 69 | ### replace 70 | 71 | - 替换路径 72 | 73 | ```json 74 | "replace":[ 75 | {"path":"/root","repalce":"./template"}, 76 | {"path":"/temp*","repalce":"./tem"} 77 | ], 78 | ``` 79 | 80 | ### proxy 81 | 82 | - 设置代理,以及j负载均衡,结构为对象数组 83 | 84 | - 每个成员包括三个成分 85 | 86 | 1. model 模式只能从RANDOM,HASH,POLLING,POLLRAN选择 87 | 88 | > random是按比重随机 89 | > 90 | > hash是通过哈希分配 91 | > 92 | > polling按比重轮询 93 | > 94 | > pollran轮询加随机 95 | 96 | 2. path为转发的路径,支持*匹配 97 | 98 | 3. host为服务器数组,格式为ip:port 99 | 100 | 4. weight为权重数组,数量应与host相同否则会出错 101 | 102 | ```json 103 | //set agent array 104 | "reverse proxy":[ 105 | {"model":"RANDOM","path":"/try*","host":["127.0.0.1:5201"],"weight":[1]} 106 | ], 107 | ``` 108 | 109 | ### 可选 110 | 111 | #### cert path 112 | 113 | - https cert位置 114 | 115 | #### key path 116 | 117 | - https key位置 118 | 119 | #### cert password 120 | 121 | - key密码(没有直接删除该行) 122 | 123 | #### memory 124 | 125 | - int类型,没有设置默认为1 126 | 127 | - 作用为设置初始发送缓冲区大小,单位为M 128 | 129 | #### thread num 130 | 131 | - 指定线程数量,int类型,默认为5 132 | 133 | - 只有在THREAD模式下才有效 134 | -------------------------------------------------------------------------------- /doc/configjson.md: -------------------------------------------------------------------------------- 1 | ## Configuration file description 2 | 3 | - The server runs by reading the config.json configuration file, please make sure the server directory has this file 4 | 5 | - The configuration file config.json uses the json format to support // and /**/ as comments 6 | 7 | ### port 8 | 9 | - bound port 10 | 11 | - If it is 0, it will be bound immediately 12 | 13 | ### defalut file 14 | 15 | - html files accessed by default 16 | - If you don't want to set it can be "" 17 | 18 | ### model 19 | 20 | - Server operating mode 21 | 22 | - can only be "MULTIPLEXING" or "FORK" or "THREAD" 23 | 24 | ### long connect 25 | 26 | - bool type, whether to enable long connection 27 | 28 | ### background 29 | 30 | - bool type, whether to run in the background 31 | 32 | ### guard 33 | 34 | - Whether to enable automatic restart when downtime 35 | 36 | ### logger 37 | 38 | - whether to enable logging 39 | 40 | ### log path 41 | 42 | - log storage path 43 | 44 | ### auto 45 | 46 | - Whether to enable automatic path recognition 47 | 48 | ### message print 49 | 50 | - bool type, whether to print the output to the terminal 51 | 52 | ### redirect 53 | 54 | - redirection, the structure is an array 55 | 56 | ```json 57 | "redirect":[ 58 | {"path":"/root","redirect":"https://baidu.com"}, 59 | {"path":"/temp","redirect":"./tem"} 60 | ], 61 | ``` 62 | 63 | ### delete path 64 | 65 | - Manually exclude paths 66 | 67 | - is an array of strings 68 | 69 | ### replace 70 | 71 | - replace path 72 | 73 | ```json 74 | "replace":[ 75 | {"path":"/root","repalce":"./template"}, 76 | {"path":"/temp*","repalce":"./tem"} 77 | ], 78 | ``` 79 | 80 | ### proxy 81 | 82 | - Set up the proxy, and j load balancing, the structure is an array of objects 83 | 84 | - Each member includes three ingredients 85 | 86 | 1. The model mode can only be selected from RANDOM, HASH, POLLING, POLLRAN 87 | 88 | > random is random by weight 89 | 90 | hash is assigned by hash 91 | 92 | > polling by weight 93 | > 94 | > pollran polling plus random 95 | 96 | 2. path is the forwarding path, supports * matching 97 | 98 | 3. host is an array of servers, the format is ip:port 99 | 100 | 4. weight is the weight array, the number should be the same as the host, otherwise an error will occur 101 | 102 | ```json 103 | //set agent array 104 | "reverse proxy":[ 105 | {"model":"RANDOM","path":"/try*","host":["127.0.0.1:5201"],"weight":[1]} 106 | ], 107 | ``` 108 | 109 | ### optional 110 | 111 | #### cert path 112 | 113 | - https cert location 114 | 115 | #### key path 116 | 117 | - https key location 118 | 119 | #### cert password 120 | 121 | - key password (do not delete this line directly) 122 | 123 | #### memory 124 | 125 | - int type, no setting defaults to 1 126 | 127 | - The function is to set the initial send buffer size, the unit is M 128 | 129 | #### thread num 130 | 131 | - Specify the number of threads, int type, the default is 5 132 | 133 | - Only works in THREAD mode 134 | -------------------------------------------------------------------------------- /doc/framework.cn.md: -------------------------------------------------------------------------------- 1 | ## 本文目的 2 | 3 | 安装cppweb框架,使用更方便 4 | 5 | ## windows 6 | 7 | > 个人使用 8 | 9 | 1. 在hpp文件夹下包含cppweb.h可以直接包含该头文件. 10 | 11 | 2. 在链接时加上-lpthread -lwsock32 12 | 13 | 3. 作用域为cppweb 14 | 15 | > 全局使用 16 | 17 | 1. 把hpp/cppweb.h放到编译器头文件就可以使用 18 | 19 | ## Linux 20 | 21 | > 个人使用 22 | 23 | 1. git clone 仓库 24 | 25 | 2. 在hpp文件夹下包含cppweb.h可以直接包含该头文件. 26 | 27 | 3. 在链接时加上-lpthread 28 | 29 | 4. 作用域为cppweb 30 | 31 | > 全局使用 32 | 33 | 1. git clone仓库 34 | 35 | 2. make install 36 | 37 | 3. 在链接时加上-lpthread 38 | 39 | 4. using namespace cppweb;(也可以不用) 40 | 41 | 5. 更新 make update 42 | 43 | 6. 删除 make uninstall 44 | -------------------------------------------------------------------------------- /doc/framework.md: -------------------------------------------------------------------------------- 1 | ## Purpose of this article 2 | 3 | Install the cppweb framework, which is more convenient to use 4 | 5 | ## windows 6 | 7 | > Personal use 8 | 9 | 1. Include cppweb.h in the hpp folder to include the header file directly. 10 | 2. Add -lpthread -lwsock32 when linking 11 | 3. The scope is cppweb 12 | 13 | > global use 14 | 15 | 1. Put hpp/cppweb.h into the compiler header file and you can use it 16 | 17 | ## Linux 18 | 19 | > Personal use 20 | 21 | 1. git clone the repository 22 | 23 | 2. Including cppweb.h in the hpp folder can directly include the header file. 24 | 25 | 3. Add -lpthread when linking 26 | 27 | 4. The scope is cppweb 28 | 29 | > global use 30 | 31 | 1. git clone repository 32 | 33 | 2. make install 34 | 35 | 3. Add -lpthread when linking 36 | 37 | 4. using namespace cppweb; (or not) 38 | 39 | 5. make update 40 | 41 | 6. Remove make uninstall 42 | -------------------------------------------------------------------------------- /doc/others.md: -------------------------------------------------------------------------------- 1 | ## 其他类说明 2 | 3 | ### ClientTcpIp 4 | 5 | - 该类为客户端类,一般用不到 6 | 7 | - 支持ssl,需#define CPPHTTPLIB_OPENSSL_SUPPORT 8 | 9 | #### 构造函数 10 | 11 | ```cpp 12 | ClientTcpIp(const char* hostIp,unsigned short port) 13 | ``` 14 | 15 | - 第一个参数为连接ip,第二个为连接的端口 16 | 17 | - 如果暂时未知填NULL 18 | 19 | #### addhostip 20 | 21 | ```cpp 22 | void addHostIp(const char* ip,unsigned short port=0) 23 | ``` 24 | 25 | - 初始化后添加或者更改ip和端口 26 | 27 | #### 其他函数类似就不介绍 28 | 29 | ## Json 30 | 31 | - 具体介绍查看[官网](ttps://gitee.com/chenxuan520/cppjson) 32 | -------------------------------------------------------------------------------- /doc/serverbuild.cn.md: -------------------------------------------------------------------------------- 1 | ## 本文目标 2 | 3 | - 使用cppweb搭建简单的http服务器和https服务器 4 | 5 | ## 脚本安装教程 6 | 7 | > linux可用 8 | 9 | 1. git clone https://gitee.com/chenxuan520/server-for-static-web.git 10 | 11 | 2. ./install.sh 12 | 13 | 3. 填入端口等信息 14 | 15 | 4. 服务器运行 16 | 17 | ##### 填入信息 18 | 19 | 5. 填入绑定的端口(如5200) 20 | 21 | 6. 填入网页默认的html文件名(index.html) 22 | 23 | 7. 填入是否运行在后台 (true or false) 24 | 25 | 8. 填入是否使用守护进程 (true or false) 26 | 27 | ## 修改配置法(推荐) 28 | 29 | > windows和linux都可 30 | 31 | 1. git clone https://gitee.com/chenxuan520/server-for-static-web.git 32 | 33 | 2. make (windows下make -f makefile.win) 34 | 35 | > 如果有https证书也可以make ssl 36 | 37 | 3. 修改config.json,[介绍](./configjson.cn.md) 38 | 39 | 4. ./main 40 | 41 | ## 信息说明 42 | 43 | - 不运行在后台的话shell结束会一起结束 44 | 45 | - 守护进程可以保证宕机快速重启 46 | 47 | ## 修改配置 48 | 49 | - 直接修改config.json 50 | 51 | - ./main --reload 52 | 53 | ## 停止服务器 54 | 55 | - ./main --stop 56 | 57 | ## 指定配置文件 58 | 59 | - ./main --config=(文件名字) 60 | 61 | ## 查看帮助 62 | 63 | - ./main --help 64 | 65 | ## 搭建https服务 66 | 67 | ### 说明 68 | 69 | 1. 用于修改配置法,脚本法无效 70 | 71 | 2. 需要提前安装openssl 72 | 73 | ```shell 74 | sudo apt install openssl libssl-dev 75 | ``` 76 | 77 | ### 1. 获取证书 78 | 79 | #### openssl自己签发(用于测试) 80 | 81 | ```shell 82 | openssl genrsa -des3 -out privkey.pem 2048 83 | openssl req -new -key privkey.pem -out cert.csr 84 | openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095 85 | ``` 86 | 87 | #### 使用域名获取ssl证书 88 | 89 | 1. 获取路径有域名购买处或者[freessl](https://freessl.cn/) 90 | 91 | 2. 下载用于nginx的证书,包含一个pem和一个key 92 | 93 | 3. 转换key为pem 94 | 95 | ```shell 96 | openssl rsa -in (key name).key -out (new name).pem 97 | ``` 98 | 99 | ### 2.修改config.h 100 | 101 | - 把"cert path"和"key path"的值改为证书路径 102 | 103 | - 如果没有密码把"cert password"这行注释 104 | 105 | ### 3. 编译运行 106 | 107 | 1. **make ssl** 108 | 109 | 2. ./main 110 | -------------------------------------------------------------------------------- /doc/serverbuild.md: -------------------------------------------------------------------------------- 1 | ## Goal of this article 2 | 3 | - Use cppweb to build a simple http server and https server 4 | 5 | ## Script installation tutorial 6 | 7 | > linux available 8 | 9 | 1. git clone https://gitee.com/chenxuan520/server-for-static-web.git 10 | 11 | 2. ./install.sh 12 | 13 | 3. Fill in the port and other information 14 | 15 | 4. Server running 16 | 17 | ##### Fill in the information 18 | 19 | 5. Fill in the bound port (eg 5200) 20 | 21 | 6. Fill in the default html file name (index.html) of the web page 22 | 23 | 7. Fill in whether to run in the background (true or false) 24 | 25 | 8. Fill in whether to use daemon (true or false) 26 | 27 | ## Modify the configuration method (recommended) 28 | 29 | > Both windows and linux are available 30 | 31 | 1. git clone https://gitee.com/chenxuan520/server-for-static-web.git 32 | 33 | 2. make (make -f makefile.win under windows) 34 | 35 | > If you have https certificate, you can also make ssl 36 | 37 | 3. Modify config.json,[introduction](./configjson.md) 38 | 39 | 4. ./main 40 | 41 | ## Information Description 42 | 43 | - If not running in the background, the shell will end together 44 | 45 | - The daemon process can ensure fast restart after downtime 46 | 47 | ## Change setting 48 | 49 | - Modify config.json directly 50 | 51 | - ./main --reload 52 | 53 | ## stop the server 54 | 55 | - ./main --stop 56 | 57 | ## Specify the configuration file 58 | 59 | - ./main --config=(file name) 60 | 61 | ## View help 62 | 63 | - ./main --help 64 | 65 | ## Build https service 66 | 67 | ### illustrate 68 | 69 | 1. Used to modify the configuration method, the script method is invalid 70 | 71 | 2. You need to install openssl in advance 72 | 73 | ```shell 74 | sudo apt install openssl libssl-dev 75 | ``` 76 | 77 | ### 1. Get the certificate 78 | 79 | #### openssl self-signed (for testing) 80 | 81 | ```shell 82 | openssl genrsa -des3 -out privkey.pem 2048 83 | openssl req -new -key privkey.pem -out cert.csr 84 | openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095 85 | ``` 86 | 87 | #### Get ssl certificate using domain name 88 | 89 | 1. The acquisition path is the domain name purchase place or [freessl](https://freessl.cn/) 90 | 91 | 2. Download the certificate for nginx, including a pem and a key 92 | 93 | 3. Convert key to pem 94 | 95 | ```shell 96 | openssl rsa -in (key name).key -out (new name).pem 97 | ``` 98 | 99 | ### 2. Modify config.h 100 | 101 | - Change the values of "cert path" and "key path" to the certificate path 102 | 103 | - if there is no password comment the line "cert password" 104 | 105 | ### 3. Compile and run 106 | 107 | 1. **make ssl** 108 | 109 | 2. ./main 110 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Welcome to chenxuan server! 8 | 15 | 16 | 17 |

Welcome chenxuan web server!

18 |

If you see this page, the web server is successfully installed and working.

19 |

For documentation and support please refer to Official website and give issue to me.
20 | If you think this project is useful,you can give it a star
21 | author web chenxuanweb.

22 |

You can contact author by email 1607772321@qq.com

23 |

Thank you for using web server.

24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo 'welcome to easy server'; 3 | echo 'choose port to bound'; 4 | read port; 5 | echo 'choose index html'; 6 | read index; 7 | echo 'choose if run in background(true or false)'; 8 | read back; 9 | echo 'choose if use guard(true or false)'; 10 | read if_guard; 11 | echo 'choose if use https(true or false)'; 12 | echo 'if use you must change certway in config.json' 13 | read https; 14 | if [ $https == 'false' ] 15 | then 16 | make 17 | else 18 | make ssl 19 | fi 20 | make clean 21 | 22 | sed -i 's!\("port":\).*!\1'"${port}"',!g' config.json 23 | sed -i 's!\("background":\).*!\1'"${back}"',!g' config.json 24 | sed -i 's!\("guard":\).*!\1'"${if_guard}"',!g' config.json 25 | sed -i 's!\("default file":"\).*!\1'"${index}"'",!g' config.json 26 | 27 | ./main 28 | echo 'every thing is ok,just enjoy it' 29 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuan520/cppweb/38c2f7f20277789ea6bd2d125b2daf7b1fff4d73/logo.png -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | #*********************************************** 2 | # Author: chenxuan-1607772321@qq.com 3 | # change time:2022-04-15 19:29:51 4 | # description: makefile of project 5 | #**********************************************/ 6 | all:main 7 | 8 | cc=g++ 9 | obj=main 10 | obj_source=./src/cpp/main.cpp 11 | pro_source=./src/hpp/cppweb.h ./src/hpp/argc.h ./src/hpp/email.h 12 | source=./src/cpp/main.cpp ./src/hpp/cppweb.h ./src/hpp/proxy.h ./src/hpp/config.h ./src/hpp/route.h ./src/hpp/argc.h 13 | link=-lpthread 14 | link_ssl=-lpthread -lssl -lcrypto 15 | ssl_macro=-D CPPWEB_OPENSSL 16 | debug_macro=-D CPPWEB_DEBUG 17 | install_dir=/usr/local/include/cppweb 18 | clean_files=server.pid access.log main ./src/example/*/main 19 | 20 | .PHONY:ssl 21 | .PHONY:main 22 | .PHONY:debug 23 | .PHONY:clean 24 | 25 | main: $(source) 26 | $(cc) -O2 $(obj_source) -o $(obj) $(link) 27 | clean: 28 | rm -f $(clean_files) 29 | ssl: $(source) 30 | $(cc) -O2 $(obj_source) -o $(obj) $(ssl_macro) $(link_ssl) 31 | debug: 32 | $(cc) -g $(obj_source) -o $(obj) $(debug_macro) $(link) 33 | ssldebug: 34 | $(cc) -g $(obj_source) -o $(obj) $(debug_macro) $(ssl_macro) $(link_ssl) 35 | install: 36 | mkdir $(install_dir) 37 | cp $(pro_source) $(install_dir) 38 | update: 39 | cp $(pro_source) $(install_dir) 40 | uninstall: 41 | rm -rf $(install_dir) 42 | -------------------------------------------------------------------------------- /makefile.win: -------------------------------------------------------------------------------- 1 | #*********************************************** 2 | # Author: chenxuan-1607772321@qq.com 3 | # change time:2022-04-15 19:29:51 4 | # description: makefile of project 5 | #**********************************************/ 6 | all:main 7 | 8 | cc=g++ 9 | obj=main 10 | obj_source=./src/cpp/main.cpp 11 | pro_source=./src/hpp/cppweb.h ./src/hpp/argc.h ./src/hpp/email.h 12 | source=./src/cpp/main.cpp ./src/hpp/cppweb.h ./src/hpp/proxy.h ./src/hpp/config.h ./src/hpp/route.h ./src/hpp/argc.h 13 | link=-lpthread -lwsock32 14 | link_ssl=-lpthread -lwsock32 -lssl -lcrypto 15 | ssl_macro=-D CPPWEB_OPENSSL 16 | debug_macro=-D CPPWEB_DEBUG 17 | compile_option=-std=c++11 18 | clean_files=server.pid access.log main.exe 19 | 20 | main: $(source) 21 | $(cc) -O2 $(obj_source) -o $(obj) $(link) $(compile_option) 22 | clean: 23 | rm -f $(clean_files) 24 | ssl: $(source) 25 | $(cc) -O2 $(obj_source) -o $(obj) $(ssl_macro) $(link_ssl) 26 | debug: 27 | $(cc) -g $(obj_source) -o $(obj) $(link) 28 | -------------------------------------------------------------------------------- /old/README.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 1. 该文件夹下所有文件均为历史版本或者一些实验性开发模块 4 | 5 | 2. 不成熟且有bug,因此不要使用 6 | -------------------------------------------------------------------------------- /old/class/guard.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | /******************************** 11 | author:chenxuan 12 | date:2021/9/8 13 | funtion:the class for create guard process 14 | parameter:isAllHide stand for use hide all mode 15 | *********************************/ 16 | class GuardProcess{ 17 | private: 18 | int pid; 19 | public: 20 | GuardProcess(bool isAllHide=false) 21 | { 22 | pid=0; 23 | pid=fork(); 24 | if(pid!=0) 25 | exit(0); 26 | if(true==isAllHide) 27 | { 28 | pid=setsid(); 29 | if(-1==pid) 30 | throw 1; 31 | pid=chdir("/"); 32 | if(-1==pid) 33 | throw 2; 34 | umask(0); 35 | close(STDERR_FILENO); 36 | close(STDIN_FILENO); 37 | close(STDOUT_FILENO); 38 | } 39 | } 40 | void working(int (*pfuncWork)(void*),void* arg) 41 | { 42 | while(pfuncWork(arg)==0); 43 | } 44 | static bool changeWorkingDir(const char* dirPath) 45 | { 46 | int temp=chdir(dirPath); 47 | if(-1==temp) 48 | return false; 49 | return true; 50 | } 51 | static inline void showLastError() 52 | { 53 | perror("last error"); 54 | } 55 | }; 56 | /******************************** 57 | author:chenxuan 58 | date:2021/9/25 59 | funtion:file class to do something 60 | *********************************/ 61 | class FileGet{ 62 | private: 63 | char* pbuffer; 64 | public: 65 | FileGet() 66 | { 67 | pbuffer=NULL; 68 | } 69 | ~FileGet() 70 | { 71 | if(pbuffer!=NULL) 72 | { 73 | free(pbuffer); 74 | pbuffer=NULL; 75 | } 76 | } 77 | int getFileLen(const char* fileName) 78 | { 79 | int len=0; 80 | FILE* fp=fopen(fileName,"rb"); 81 | if(fp==NULL) 82 | return -1; 83 | fseek(fp,0,SEEK_END); 84 | len=ftell(fp); 85 | fclose(fp); 86 | return len; 87 | } 88 | bool getFileMsg(const char* fileName,char* buffer) 89 | { 90 | int i=0,len=0; 91 | len=this->getFileLen(fileName); 92 | FILE* fp=fopen(fileName,"rb"); 93 | if(fp==NULL) 94 | return false; 95 | for(i=0;igetFileLen(fileName); 106 | if(pbuffer!=NULL) 107 | { 108 | free(pbuffer); 109 | pbuffer=NULL; 110 | } 111 | FILE* fp=fopen(fileName,"r"); 112 | if(fp==NULL) 113 | return false; 114 | pbuffer=(char*)malloc(sizeof(char)*(len+10)); 115 | char* ptemp=pbuffer; 116 | if(pbuffer==NULL) 117 | return false; 118 | memset(pbuffer,0,sizeof(char)*(len+5)); 119 | if(false==this->getFileMsg(fileName,pbuffer)) 120 | return false; 121 | while((*ptemp<65||*ptemp>122)&&ptemp 4 | #include 5 | #include 6 | #include 7 | namespace cppweb{ 8 | class IniConfig{ 9 | public: 10 | class Object{ 11 | public: 12 | Object(const std::string& value):value(value),error(NULL){} 13 | inline std::string toString(){ 14 | return value; 15 | } 16 | int toFloat(){ 17 | float result=0; 18 | auto flag=sscanf(value.c_str(),"%f",&result); 19 | if(flag<=0){ 20 | error=(value+std::string(" cannot be float")).c_str(); 21 | return -1; 22 | } 23 | return result; 24 | } 25 | int toBool(){ 26 | if(value=="true"){ 27 | return true; 28 | }else if(value=="false"){ 29 | return false; 30 | }else{ 31 | error=(value+std::string(" cannot be bool")).c_str(); 32 | return false; 33 | } 34 | } 35 | int toInt(){ 36 | int result=0; 37 | auto flag=sscanf(value.c_str(),"%d",&result); 38 | if(flag<=0){ 39 | error=(value+std::string(" cannot be int")).c_str(); 40 | return -1; 41 | } 42 | return result; 43 | } 44 | private: 45 | std::string value; 46 | const char* error; 47 | }; 48 | typedef std::unordered_map> KeyMap; 49 | private: 50 | KeyMap root; 51 | std::string data; 52 | const char* error; 53 | public: 54 | IniConfig(const std::string& data):data(data),error(NULL){ 55 | deleteComment(this->data); 56 | std::vector arr; 57 | stringSplit(arr,data,'\n'); 58 | analyseText(arr); 59 | }; 60 | inline const KeyMap& getAnalyseResult(){ 61 | return root; 62 | } 63 | std::string createConfig(const KeyMap& root){ 64 | std::string result; 65 | for(auto iter:root){ 66 | result+="["+iter.first+"]\n"; 67 | for(auto now:iter.second){ 68 | result+=now.first+" = "+now.second.toString()+"\n"; 69 | } 70 | } 71 | return result; 72 | } 73 | inline const char* lastError(){ 74 | return error; 75 | } 76 | public: 77 | bool analyseText(std::vector& arr){ 78 | std::string section; 79 | bool flag=true; 80 | for(auto& now:arr){ 81 | if(now.size()==0){ 82 | continue; 83 | } 84 | if(now[0]=='['){ 85 | flag=findSection(section,now); 86 | if(!flag){ 87 | return false; 88 | }else{ 89 | root.insert({section,std::unordered_map()}); 90 | } 91 | }else{ 92 | if(section.size()==0){ 93 | error="can not find begin section"; 94 | return false; 95 | } 96 | flag=findKeyValue(now,root[section]); 97 | if(!flag){ 98 | return false; 99 | } 100 | } 101 | } 102 | return true; 103 | } 104 | void deleteComment(std::string& data){ 105 | std::string temp; 106 | bool flag=false; 107 | for(auto ch:data){ 108 | if(ch=='\n'){ 109 | flag=false; 110 | }else if(ch==';'){ 111 | flag=true; 112 | }else if(ch=='\r'||ch==' '){ 113 | continue; 114 | } 115 | if(!flag){ 116 | temp+=ch; 117 | } 118 | } 119 | data=temp; 120 | } 121 | private: 122 | bool findSection(std::string& result,const std::string data){ 123 | result.clear(); 124 | if(data.size()==0||data[0]!='['){ 125 | error="section begin without ["; 126 | return false; 127 | } 128 | if(data.find(']')==data.npos){ 129 | error="section end without ]"; 130 | return false; 131 | } 132 | auto pos=data.find(']'); 133 | result=data.substr(1,pos-1); 134 | return true; 135 | } 136 | bool findKeyValue(const std::string& data,std::unordered_map& result){ 137 | if(data.find('=')==data.npos){ 138 | error="can not find ="; 139 | return false; 140 | } 141 | auto pos=data.find('='); 142 | result.insert({data.substr(0,pos),data.substr(pos+1,data.size())}); 143 | return true; 144 | } 145 | void stringSplit(std::vector& elems,const std::string& str, char delim) { 146 | std::size_t previous = 0; 147 | std::size_t current = str.find(delim); 148 | while (current != std::string::npos) { 149 | if (current > previous) { 150 | elems.push_back(str.substr(previous, current - previous)); 151 | } 152 | previous = current + 1; 153 | current = str.find(delim, previous); 154 | } 155 | if (previous != str.size()) { 156 | elems.push_back(str.substr(previous)); 157 | } 158 | } 159 | }; 160 | }; 161 | -------------------------------------------------------------------------------- /old/class/memory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | class CheckMemory{ 7 | private: 8 | struct Node{ 9 | void* ptr; 10 | Node* pnext; 11 | size_t len; 12 | }; 13 | Node* memory; 14 | const char* error; 15 | FILE* fp; 16 | unsigned all; 17 | unsigned hashNum; 18 | public: 19 | CheckMemory(unsigned hashNums=997) 20 | { 21 | if(hashNums<13) 22 | hashNum=hashNums; 23 | else 24 | hashNum=997; 25 | #ifndef FILE_SAVE_NAME 26 | printf("recording...\n"); 27 | fp=NULL; 28 | #else 29 | fp=fopen(FILE_SAVE_NAME,"a+"); 30 | #endif 31 | memory=(Node*)malloc(sizeof(Node)*hashNum); 32 | error=NULL; 33 | all=0; 34 | if(memory==NULL) 35 | { 36 | error="malloc wrong"; 37 | return; 38 | } 39 | memset(memory,0,sizeof(Node)*hashNum); 40 | } 41 | ~CheckMemory() 42 | { 43 | #ifndef FILE_SAVE_NAME 44 | printf("checking...\n"); 45 | #else 46 | if(fp!=NULL) 47 | { 48 | time_t now=time(NULL); 49 | fprintf(fp,"Date:%s\n",ctime(&now)); 50 | } 51 | #endif 52 | for(unsigned i=0;ipnext; 56 | while(now!=NULL) 57 | { 58 | all+=now->len; 59 | #ifndef FILE_SAVE_NAME 60 | printf("leak %zu memory\n",now->len); 61 | #else 62 | if(fp!=NULL) 63 | fprintf(fp,"leak:%zu\n",now->len); 64 | #endif 65 | now=now->pnext; 66 | } 67 | } 68 | #ifndef FILE_SAVE_NAME 69 | printf("all leck:%u\n\n",all); 70 | #else 71 | if(fp!=NULL) 72 | fprintf(fp,"all leak:%u\n\n",all); 73 | #endif 74 | if(memory!=NULL) 75 | free(memory); 76 | if(fp!=NULL) 77 | fclose(fp); 78 | } 79 | void insert(void* pmalloc,size_t size) 80 | { 81 | if(size==0||error!=NULL) 82 | return; 83 | long int temp=(long int)pmalloc; 84 | temp%=hashNum; 85 | Node* now=memory+temp; 86 | while(now->pnext!=NULL) 87 | now=now->pnext; 88 | now->pnext=(Node*)malloc(sizeof(Node)); 89 | if(now->pnext==NULL) 90 | { 91 | error="malloc wrong"; 92 | return; 93 | } 94 | now->len=size; 95 | now=now->pnext; 96 | now->len=size; 97 | now->pnext=NULL; 98 | now->ptr=pmalloc; 99 | } 100 | void change(void* pfree,void* newPtr,size_t newLen) 101 | { 102 | if(pfree==NULL||error!=NULL) 103 | return; 104 | long int temp=(long int)pfree; 105 | temp%=hashNum; 106 | Node* now=memory+temp,*last=now; 107 | if(now==NULL) 108 | return; 109 | now=now->pnext; 110 | while(now!=NULL) 111 | { 112 | if(now->ptr==pfree) 113 | { 114 | now->ptr=newPtr; 115 | now->len=newLen; 116 | break; 117 | } 118 | last=now; 119 | now=now->pnext; 120 | } 121 | } 122 | void erase(void* pfree) 123 | { 124 | if(pfree==NULL||error!=NULL) 125 | return; 126 | long int temp=(long int)pfree; 127 | temp%=hashNum; 128 | Node* now=memory+temp,*last=now; 129 | if(now==NULL) 130 | return; 131 | now=now->pnext; 132 | while(now!=NULL) 133 | { 134 | if(now->ptr==pfree) 135 | { 136 | last->pnext=now->pnext; 137 | free(now); 138 | now=NULL; 139 | break; 140 | } 141 | last=now; 142 | now=now->pnext; 143 | } 144 | } 145 | }checkMemory; 146 | void* operator new(size_t size) 147 | { 148 | void* result=malloc(size); 149 | checkMemory.insert(result,size); 150 | return result; 151 | } 152 | void* operator new[](size_t size) 153 | { 154 | void* result=malloc(size); 155 | checkMemory.insert(result,size); 156 | return result; 157 | } 158 | void operator delete(void* ptr) noexcept 159 | { 160 | checkMemory.erase(ptr); 161 | free(ptr); 162 | } 163 | void operator delete[](void* ptr) noexcept 164 | { 165 | if(ptr==NULL) 166 | return; 167 | checkMemory.erase(ptr); 168 | free(ptr); 169 | } 170 | void* Malloc_now(size_t size) 171 | { 172 | void* temp=malloc(size); 173 | if(temp!=NULL) 174 | checkMemory.insert(temp,size); 175 | return temp; 176 | } 177 | inline void Free_now(void* ptr) 178 | { 179 | checkMemory.erase(ptr); 180 | free(ptr); 181 | } 182 | void* Realloc_now(void* ptr,size_t size) 183 | { 184 | void* temp=realloc(ptr,size); 185 | checkMemory.change(ptr,temp,size); 186 | return temp; 187 | } 188 | #define malloc(x) Malloc_now(x) 189 | #define free(x) Free_now(x) 190 | #define realloc(x,y) Realloc_now(x,y) 191 | -------------------------------------------------------------------------------- /old/class/sqlInstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | git clone https://gitclone.com/github.com/redis/hiredis.git 3 | cd hiredis 4 | make 5 | make install 6 | /sbin/ldconfig 7 | apt-get install libmysqlclient-dev libmysql++-dev 8 | cd .. 9 | make sql 10 | echo 'install redis and mysql ok' 11 | -------------------------------------------------------------------------------- /old/class/threadPool.cpp: -------------------------------------------------------------------------------- 1 | /******************************** 2 | author:chenxuan 3 | date:2021.7.14 4 | funtion:this file is a try for thead pool 5 | *********************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | /******************************** 20 | author:chenxuan 21 | date:2021.7.17 22 | funtion:this is a class for thread pool 23 | *********************************/ 24 | template 25 | class ThreadPool{ 26 | public://a struct for you to add task 27 | struct Task{ 28 | void* (*ptask)(T); 29 | T arg; 30 | }; 31 | private: 32 | mutex queLock; 33 | mutex userLock; 34 | condition_variable condition; 35 | queue que; 36 | unsigned threadNum; 37 | atomic busyNow; 38 | atomic isContinue; 39 | vector arr; 40 | const char* error; 41 | public: 42 | ThreadPool(unsigned threadNum=10) 43 | { 44 | error=NULL; 45 | this->threadNum=threadNum; 46 | for(unsigned i=0;ijoin(); 57 | delete arr[i]; 58 | } 59 | } 60 | inline void mutexLock() 61 | { 62 | userLock.lock(); 63 | } 64 | inline void mutexUnlock() 65 | { 66 | userLock.unlock(); 67 | } 68 | void addTask(Task task) 69 | { 70 | unique_lock guard(this->queLock); 71 | this->que.push(task); 72 | this->condition.notify_one(); 73 | } 74 | void stopPool() 75 | { 76 | isContinue=false; 77 | this->condition.notify_all(); 78 | } 79 | void getBusyAndTask(unsigned& busy,unsigned& task) 80 | { 81 | unique_lock guard(this->queLock); 82 | task=this->que.size(); 83 | busy=this->busyNow; 84 | } 85 | private: 86 | static void worker(void* arg) 87 | { 88 | ThreadPool& pool=*(ThreadPool*)arg; 89 | Task task={0,0}; 90 | while(1) 91 | { 92 | { 93 | unique_lock guard(pool.queLock); 94 | if(pool.isContinue&&pool.que.size()==0) 95 | pool.condition.wait(guard,[&]()->bool{ 96 | return pool.que.size()>0||pool.isContinue==false; 97 | }); 98 | if(pool.isContinue==false) 99 | return ; 100 | if(pool.que.size()==0) 101 | continue; 102 | task=pool.que.front(); 103 | pool.que.pop(); 104 | } 105 | pool.busyNow++; 106 | if(task.ptask!=NULL) 107 | task.ptask(task.arg); 108 | pool.busyNow--; 109 | } 110 | } 111 | }; 112 | class LogSystem{ 113 | private: 114 | struct BufferList{ 115 | char* buffer; 116 | BufferList* pnext; 117 | }; 118 | private: 119 | const char* fileName; 120 | BufferList* buffer; 121 | BufferList* nowBuffer; 122 | BufferList* saveBuffer; 123 | const char* error; 124 | size_t nowLen; 125 | size_t bufferLen; 126 | pthread_t pid; 127 | bool isBusy; 128 | bool isContinue; 129 | sem_t sem; 130 | public: 131 | LogSystem(const char* name,size_t bufferLen=1024):fileName(name) 132 | { 133 | nowLen=0; 134 | pid=0; 135 | nowBuffer=NULL; 136 | error=NULL; 137 | saveBuffer=NULL; 138 | if(bufferLen<128) 139 | bufferLen=128; 140 | if(fileName==NULL) 141 | fileName="access.log"; 142 | this->bufferLen=bufferLen; 143 | buffer=(BufferList*)malloc(sizeof(BufferList)); 144 | if(buffer==NULL) 145 | { 146 | error="malloc wrong"; 147 | return; 148 | } 149 | buffer->buffer=(char*)malloc(sizeof(char)*bufferLen); 150 | if(buffer->buffer==NULL) 151 | { 152 | error="malloc wrong"; 153 | return; 154 | } 155 | buffer->pnext=NULL; 156 | BufferList* last=buffer; 157 | for(unsigned i=0;i<4;i++) 158 | { 159 | last->pnext=(BufferList*)malloc(sizeof(BufferList)); 160 | if(last->pnext==NULL) 161 | { 162 | error="malloc wrong"; 163 | return; 164 | } 165 | last=last->pnext; 166 | last->buffer=(char*)malloc(sizeof(char)*bufferLen); 167 | last->pnext=NULL; 168 | if(last->buffer==NULL) 169 | { 170 | error="malloc wrong"; 171 | return; 172 | } 173 | memset(last->buffer,0,sizeof(char)*bufferLen); 174 | } 175 | last->pnext=buffer; 176 | nowBuffer=buffer; 177 | saveBuffer=nowBuffer; 178 | sem_init(&sem,1,0); 179 | isBusy=false; 180 | isContinue=true; 181 | /* pid=ThreadPool::createPthread(this,worker); */ 182 | } 183 | ~LogSystem() 184 | { 185 | isContinue=false; 186 | sem_post(&sem); 187 | /* if(pid!=0) */ 188 | /* ThreadPool::waitPthread(pid); */ 189 | sem_destroy(&sem); 190 | nowBuffer=nowBuffer->pnext; 191 | BufferList* last=buffer; 192 | while(last!=NULL) 193 | { 194 | BufferList* temp=last; 195 | if(last->buffer!=NULL) 196 | free(last->buffer); 197 | if(last->pnext!=buffer) 198 | { 199 | last=last->pnext; 200 | free(temp); 201 | } 202 | else 203 | { 204 | free(last); 205 | break; 206 | } 207 | } 208 | } 209 | public: 210 | inline const char* lastError() 211 | { 212 | return error; 213 | } 214 | void accessLog(const char* text) 215 | { 216 | if(strlen(text)+nowLen>bufferLen) 217 | { 218 | if(nowBuffer->pnext==saveBuffer) 219 | { 220 | if(!isBusy) 221 | sem_post(&sem); 222 | while(nowBuffer->pnext==saveBuffer); 223 | nowBuffer=nowBuffer->pnext; 224 | memset(nowBuffer->buffer,0,sizeof(char)*bufferLen); 225 | nowLen=0; 226 | } 227 | else 228 | { 229 | nowBuffer=nowBuffer->pnext; 230 | memset(nowBuffer->buffer,0,sizeof(char)*bufferLen); 231 | nowLen=0; 232 | if(!isBusy) 233 | sem_post(&this->sem); 234 | } 235 | } 236 | strcat(nowBuffer->buffer,text); 237 | strcat(nowBuffer->buffer,"\n"); 238 | nowLen+=strlen(text)+1; 239 | } 240 | /* static void recordRequest(const void* text,int soc) */ 241 | /* { */ 242 | /* static char method[32]={0},askPath[256]={0},buffer[512]={0}; */ 243 | /* static LogSystem loger("access.log"); */ 244 | /* int port=0; */ 245 | /* sscanf((char*)text,"%32s%256s",method,askPath); */ 246 | /* time_t now=time(NULL); */ 247 | /* sprintf(buffer,"%s %s %s %s",ctime(&now),ServerTcpIp::getPeerIp(soc,&port),method,askPath); */ 248 | /* loger.accessLog(buffer); */ 249 | /* } */ 250 | private: 251 | static void* worker(void* argv) 252 | { 253 | LogSystem& self=*(LogSystem*)argv; 254 | FILE* fp=fopen(self.fileName,"a+"); 255 | if(fp==NULL) 256 | { 257 | self.error="open file wrong"; 258 | return NULL; 259 | } 260 | while(self.isContinue) 261 | { 262 | sem_wait(&self.sem); 263 | self.isBusy=true; 264 | while(self.saveBuffer!=self.nowBuffer) 265 | { 266 | fprintf(fp,"%s",self.saveBuffer->buffer); 267 | memset(self.saveBuffer->buffer,0,sizeof(char)*self.bufferLen); 268 | self.saveBuffer=self.saveBuffer->pnext; 269 | } 270 | self.isBusy=false; 271 | } 272 | fprintf(fp,"%s",self.saveBuffer->buffer); 273 | fclose(fp); 274 | return NULL; 275 | } 276 | }; 277 | int temp=0; 278 | void* print(int arg) 279 | { 280 | /* unsigned int pid=(unsigned)this_thread::get_id(); */ 281 | temp++; 282 | // cout< pool(10); 292 | int ha=0; 293 | ThreadPool::Task task{print,ha}; 294 | unsigned int thread=1; 295 | unsigned int busy=0; 296 | for(unsigned int i=0;i<1000;i++) 297 | { 298 | task.arg++; 299 | pool.addTask(task); 300 | } 301 | while(thread>0) 302 | { 303 | pool.getBusyAndTask(thread,busy); 304 | printf("%u busy %u task\n",thread,busy); 305 | usleep(7); 306 | } 307 | sleep(2); 308 | return 0; 309 | } 310 | -------------------------------------------------------------------------------- /old/class/webtoken.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | class WebToken{ 5 | private: 6 | char* backString; 7 | char err[30]; 8 | public: 9 | WebToken() 10 | { 11 | backString=NULL; 12 | memset(err,0,sizeof(char)*30); 13 | sprintf(err,"no error"); 14 | } 15 | const char* createToken(const char* key,const char* encryption,char* getString,unsigned int stringLen,unsigned int liveSecond) 16 | { 17 | int temp=0; 18 | if(key==NULL||encryption==NULL||getString==NULL||stringLen 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | /******************************** 9 | author:chenxuan 10 | date:2021/9/29 11 | funtion:enhance class for guard can guard many things at the same time 12 | *********************************/ 13 | class GuardProcess{ 14 | private: 15 | int pid; 16 | public: 17 | GuardProcess(bool isAllHide=false) 18 | { 19 | pid=0; 20 | pid=fork(); 21 | if(pid!=0) 22 | exit(0); 23 | if(true==isAllHide) 24 | { 25 | pid=setsid(); 26 | if(-1==pid) 27 | throw 1; 28 | pid=chdir("/"); 29 | if(-1==pid) 30 | throw 2; 31 | umask(0); 32 | close(STDERR_FILENO); 33 | close(STDIN_FILENO); 34 | close(STDOUT_FILENO); 35 | } 36 | } 37 | void working(int (*pfuncWork)(void*),void* arg) 38 | { 39 | while(pfuncWork(arg)==0); 40 | } 41 | static bool changeWorkingDir(const char* dirPath) 42 | { 43 | int temp=chdir(dirPath); 44 | if(-1==temp) 45 | return false; 46 | return true; 47 | } 48 | static inline void showLastError() 49 | { 50 | perror("last error"); 51 | } 52 | }; 53 | /******************************** 54 | author:chenxuan 55 | date:2021/9/25 56 | funtion:file class to do something 57 | *********************************/ 58 | class FileGet{ 59 | private: 60 | char* pbuffer; 61 | public: 62 | FileGet() 63 | { 64 | pbuffer=NULL; 65 | } 66 | ~FileGet() 67 | { 68 | if(pbuffer!=NULL) 69 | { 70 | free(pbuffer); 71 | pbuffer=NULL; 72 | } 73 | } 74 | int getFileLen(const char* fileName) 75 | { 76 | int len=0; 77 | FILE* fp=fopen(fileName,"rb"); 78 | if(fp==NULL) 79 | return -1; 80 | fseek(fp,0,SEEK_END); 81 | len=ftell(fp); 82 | fclose(fp); 83 | return len; 84 | } 85 | bool getFileMsg(const char* fileName,char* buffer) 86 | { 87 | int i=0,len=0; 88 | len=this->getFileLen(fileName); 89 | FILE* fp=fopen(fileName,"rb"); 90 | if(fp==NULL) 91 | return false; 92 | for(i=0;igetFileLen(fileName); 103 | if(pbuffer!=NULL) 104 | { 105 | free(pbuffer); 106 | pbuffer=NULL; 107 | } 108 | FILE* fp=fopen(fileName,"r"); 109 | if(fp==NULL) 110 | return false; 111 | pbuffer=(char*)malloc(sizeof(char)*(len+10)); 112 | char* ptemp=pbuffer; 113 | if(pbuffer==NULL) 114 | return false; 115 | memset(pbuffer,0,sizeof(char)*(len+5)); 116 | if(false==this->getFileMsg(fileName,pbuffer)) 117 | return false; 118 | while((*ptemp<65||*ptemp>122)&&ptemp temp",worker); 204 | printf("sys:%s\n",sys); 205 | system(sys); 206 | memset(sys,0,sizeof(char)*64); 207 | if(false==file.fileStrstr("./temp",worker)) 208 | { 209 | GuardProcess::changeWorkingDir(get); 210 | sprintf(sys,"./%s",worker); 211 | printf("sys:%s\n",sys); 212 | system(sys); 213 | } 214 | memset(get,0,sizeof(char)*128); 215 | memset(worker,0,sizeof(char)*64); 216 | } 217 | for(int i=0;i<10;i++) 218 | free(buffer[i]); 219 | free(buffer); 220 | sleep(10); 221 | return 0; 222 | } 223 | int main(int argc,char** argv) 224 | { 225 | GuardProcess proess; 226 | proess.working(worker,NULL); 227 | return 0; 228 | } 229 | -------------------------------------------------------------------------------- /old/cpp/guardHttp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | /******************************** 9 | author:chenxuan 10 | date:2021/9/8 11 | funtion:the class for create guard process 12 | parameter:isAllHide stand for use hide all mode 13 | *********************************/ 14 | class GuardProcess{ 15 | private: 16 | int pid; 17 | public: 18 | GuardProcess(bool isAllHide=false) 19 | { 20 | pid=0; 21 | pid=fork(); 22 | if(pid!=0) 23 | exit(0); 24 | if(true==isAllHide) 25 | { 26 | pid=setsid(); 27 | if(-1==pid) 28 | throw 1; 29 | pid=chdir("/"); 30 | if(-1==pid) 31 | throw 2; 32 | umask(0); 33 | close(STDERR_FILENO); 34 | close(STDIN_FILENO); 35 | close(STDOUT_FILENO); 36 | } 37 | } 38 | void working(int (*pfuncWork)(void*),void* arg) 39 | { 40 | while(pfuncWork(arg)==0); 41 | } 42 | static bool changeWorkingDir(const char* dirPath) 43 | { 44 | int temp=chdir(dirPath); 45 | if(-1==temp) 46 | return false; 47 | return true; 48 | } 49 | static inline void showLastError() 50 | { 51 | perror("last error"); 52 | } 53 | }; 54 | /******************************** 55 | author:chenxuan 56 | date:2021/9/25 57 | funtion:file class to do something 58 | *********************************/ 59 | class FileGet{ 60 | private: 61 | char* pbuffer; 62 | public: 63 | FileGet() 64 | { 65 | pbuffer=NULL; 66 | } 67 | ~FileGet() 68 | { 69 | if(pbuffer!=NULL) 70 | { 71 | free(pbuffer); 72 | pbuffer=NULL; 73 | } 74 | } 75 | int getFileLen(const char* fileName) 76 | { 77 | int len=0; 78 | FILE* fp=fopen(fileName,"rb"); 79 | if(fp==NULL) 80 | return -1; 81 | fseek(fp,0,SEEK_END); 82 | len=ftell(fp); 83 | fclose(fp); 84 | return len; 85 | } 86 | bool getFileMsg(const char* fileName,char* buffer) 87 | { 88 | int i=0,len=0; 89 | len=this->getFileLen(fileName); 90 | FILE* fp=fopen(fileName,"rb"); 91 | if(fp==NULL) 92 | return false; 93 | for(i=0;igetFileLen(fileName); 104 | if(pbuffer!=NULL) 105 | { 106 | free(pbuffer); 107 | pbuffer=NULL; 108 | } 109 | FILE* fp=fopen(fileName,"r"); 110 | if(fp==NULL) 111 | return false; 112 | pbuffer=(char*)malloc(sizeof(char)*(len+10)); 113 | char* ptemp=pbuffer; 114 | if(pbuffer==NULL) 115 | return false; 116 | memset(pbuffer,0,sizeof(char)*(len+5)); 117 | if(false==this->getFileMsg(fileName,pbuffer)) 118 | return false; 119 | while((*ptemp<65||*ptemp>122)&&ptemp temp",name); 144 | system(sys); 145 | memset(sys,0,sizeof(char)*50); 146 | if(false==file.fileStrstr("./temp",name)) 147 | { 148 | printf("guard:%s\n",name); 149 | sprintf(sys,"./%s",name); 150 | system(sys); 151 | } 152 | return 0; 153 | } 154 | int main(int argc,char** argv) 155 | { 156 | char nameGuard[20]={0}; 157 | if(argc==1) 158 | { 159 | printf("please input the name of guard:"); 160 | scanf("%s",nameGuard); 161 | } 162 | GuardProcess process; 163 | if(argc>1) 164 | { 165 | printf("argv %s\n",argv[1]); 166 | process.working(func,argv[1]); 167 | } 168 | else 169 | process.working(func,nameGuard); 170 | return 0; 171 | } 172 | -------------------------------------------------------------------------------- /old/cpp/mainold.cpp: -------------------------------------------------------------------------------- 1 | /******************************** 2 | author:chenxuan 3 | date:2021.7.5 4 | funtion:this is main cpp for static web 5 | *********************************/ 6 | //#include"../hpp/sql.h" 7 | #include "../hpp/cppweb.h" 8 | #include"../hpp/dealask.h" 9 | #include 10 | #include 11 | #include 12 | using namespace cppweb; 13 | char indexName[100]="index.html"; 14 | int memory=0; 15 | /******************************** 16 | author:chenxuan 17 | date:2021.7.5 18 | funtion:main function to deal ask 19 | *********************************/ 20 | int funcTwo(ServerTcpIp::Thing thing,int num,int,void* pget,void* sen,ServerTcpIp& server)//main deal func 21 | { 22 | char ask[200]={0}; 23 | static DealHttp http; 24 | DealAsk dealAsk; 25 | int len=0; 26 | int flag=0; 27 | if(sen==NULL) 28 | return -1; 29 | memset(sen,0,sizeof(char)*memory*1024*1024); 30 | // if(false==DealAttack::dealAttack(thing,num,200)) 31 | // { 32 | // DealAttack::attackLog(port,server.getPeerIp(num,&port),"./rec/attackLog.txt"); 33 | // server.disconnectSocketEpoll(num); 34 | // return 0; 35 | // } 36 | if(thing==ServerTcpIp::CPPOUT) 37 | dealAsk.dealClientOut(server,http,pget,sen,num); 38 | if(thing==ServerTcpIp::CPPIN) 39 | dealAsk.dealClientIn(server,http,pget,sen,num); 40 | if(thing==ServerTcpIp::CPPOUT) 41 | { 42 | if(strstr((char*)pget,"POST")!=NULL) 43 | { 44 | if(false==dealAsk.dealPostAsk(server,http,pget,sen,num)) 45 | return 0; 46 | } 47 | else if(strstr((char*)pget,"GET")!=NULL) 48 | { 49 | printf("http:%s\n",http.analysisHttpAsk(pget)); 50 | strcpy(ask,http.analysisHttpAsk(pget)); 51 | if(false==dealAsk.dealGetAsk(server,http,pget,sen,num)) 52 | { 53 | flag=http.autoAnalysisGet((char*)pget,(char*)sen,sizeof(char)*memory*1024*1024,indexName,&len); 54 | if(0==flag) 55 | printf("some thing wrong %s\n",(char*)sen); 56 | else if(flag==1) 57 | printf("create auto success\n"); 58 | else if(flag==2) 59 | { 60 | FILE* fp=fopen("wrong.txt","a+"); 61 | if(fp==NULL) 62 | fp=fopen("wrong.txt","w+"); 63 | if(fp==NULL) 64 | return 0; 65 | fprintf(fp,"can not open file %s\n",ask); 66 | printf("cannot open file %s\n",ask); 67 | fclose(fp); 68 | } 69 | } 70 | } 71 | else 72 | return 0; 73 | if(0>=server.sendSocket(num,sen,len)) 74 | printf("send wrong\n"); 75 | else 76 | printf("send success\n"); 77 | } 78 | return 0; 79 | } 80 | /******************************** 81 | author:chenxuan 82 | date:2021.7.5 83 | funtion:if no argc an file use it to init 84 | *********************************/ 85 | void chooseModel(unsigned int* port,bool* pflag) 86 | { 87 | char temp[10]={0}; 88 | printf("please input the import(default 80):"); 89 | scanf("%u",port); 90 | printf("please input index.html(default index.html):"); 91 | scanf("%s",indexName); 92 | printf("please input if run in background(default no)y/n:"); 93 | fflush(stdin); 94 | scanf("%s",temp); 95 | printf("please input memory(M):"); 96 | fflush(stdin); 97 | scanf("%d",&memory); 98 | if(strchr(temp,'y')!=NULL) 99 | *pflag=true; 100 | else 101 | *pflag=false; 102 | FILE* fp=fopen("my.ini","r+"); 103 | if(fp!=NULL) 104 | { 105 | fclose(fp); 106 | return; 107 | } 108 | fp=fopen("my.ini","w+"); 109 | if(fp==NULL) 110 | return; 111 | fprintf(fp,"%u %s %d %s",*port,indexName,memory,temp); 112 | fclose(fp); 113 | } 114 | /******************************** 115 | author:chenxuan 116 | date:2021.7.5 117 | funtion:from file init server 118 | *********************************/ 119 | void ifChoose(bool* pb,unsigned int* pport,bool* is_back) 120 | { 121 | char temp[10]={0}; 122 | FILE* fp=fopen("my.ini","r+"); 123 | if(fp==NULL) 124 | { 125 | *pb=false; 126 | return; 127 | } 128 | if(fscanf(fp,"%u",pport)!=1) 129 | { 130 | *pb=false; 131 | printf("port=%u\n",*pport); 132 | return; 133 | } 134 | if(fscanf(fp,"%s",indexName)!=1) 135 | { 136 | *pb=false; 137 | printf("name:%s\n",indexName); 138 | return; 139 | } 140 | if(fscanf(fp,"%d",&memory)!=1) 141 | { 142 | *pb=false; 143 | printf("memory=%d\n",memory); 144 | return; 145 | } 146 | if(fscanf(fp,"%s",temp)!=1) 147 | { 148 | *pb=false; 149 | printf("is back wrong\n"); 150 | return; 151 | } 152 | if(strchr(temp,'y')!=NULL) 153 | *is_back=true; 154 | else 155 | *is_back=false; 156 | *pb=true; 157 | fclose(fp); 158 | return; 159 | } 160 | /******************************** 161 | author:chenxuan 162 | date:2021.7.5 163 | funtion:from argv to init server 164 | *********************************/ 165 | bool ifArgc(int argc,char** argv,bool* pis_back,unsigned int* pport) 166 | { 167 | if(argc!=5) 168 | return false; 169 | if(sscanf(argv[1],"%d",pport)!=1) 170 | { 171 | printf("init wrong\n"); 172 | return false; 173 | } 174 | sscanf(argv[2],"%s",indexName); 175 | if(sscanf(argv[3],"%d",&memory)!=1) 176 | { 177 | printf("memory wrong\n"); 178 | return false; 179 | } 180 | if(strchr(argv[4],'y')!=NULL) 181 | *pis_back=true; 182 | return true; 183 | } 184 | /******************************** 185 | author:chenxuan 186 | date:2021.7.5 187 | funtion:server begin 188 | *********************************/ 189 | void serverHttp(int argc,char** argv) 190 | { 191 | unsigned int port=80; 192 | bool is_back=false,is_choose=false; 193 | ifChoose(&is_choose,&port,&is_back); 194 | if(ifArgc(argc,argv,&is_back,&port)==false&&is_choose==false) 195 | chooseModel(&port,&is_back); 196 | if(is_back) 197 | { 198 | int pid=0; 199 | if((pid=fork())!=0) 200 | { 201 | printf("pid=%d\n",pid); 202 | return; 203 | } 204 | } 205 | ServerTcpIp server((unsigned short)port,100); 206 | char get[2048]={0}; 207 | char* sen=(char*)malloc(sizeof(char)*memory*1024*1024); 208 | if(sen==NULL) 209 | printf("memory wrong\n"); 210 | // HttpServer server(5200); 211 | // server.run(1,"./index.html"); 212 | if(false==server.bondhost()) 213 | { 214 | printf("bound wrong\n"); 215 | exit(0); 216 | } 217 | if(false==server.setlisten()) 218 | exit(0); 219 | printf("the server is ok\n"); 220 | while(1) 221 | if(false==server.epollModel(get,2048,sen,funcTwo)) 222 | break; 223 | free(sen); 224 | } 225 | int main(int argc, char** argv) 226 | { 227 | serverHttp(argc,argv); 228 | return 0; 229 | } 230 | -------------------------------------------------------------------------------- /old/cpp/my.ini: -------------------------------------------------------------------------------- 1 | 5200 index.html 1 n 2 | -------------------------------------------------------------------------------- /old/hpp/thread.h: -------------------------------------------------------------------------------- 1 | #ifndef _THREAD_H_ 2 | #define _THREAD_H_ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include"server.h" 22 | /******************************** 23 | author:chenxuan 24 | date:2021/8/10 25 | funtion:class thread pool 26 | *********************************/ 27 | namespace cppweb{ 28 | using namespace cppweb; 29 | class ThreadPool{ 30 | public://a struct for you to add task 31 | struct Task{ 32 | void* (*ptask)(void*); 33 | void* arg; 34 | }; 35 | private: 36 | std::queue thingWork;//a queue for struct task 37 | pthread_cond_t condition;//a condition mutex 38 | pthread_mutex_t lockPoll;//a lock to lock queue 39 | pthread_mutex_t lockTask;//a lock for user to ctrl 40 | pthread_mutex_t lockBusy;//a lock for busy thread 41 | pthread_t* thread;//an array for thread 42 | pthread_t threadManager;//thread for manager user to ctrl 43 | unsigned int liveThread;//num for live thread 44 | unsigned int busyThread;//num for busy thread 45 | bool isContinue;//if the pool is continue 46 | private: 47 | static void* worker(void* arg);//the worker for user 48 | static void* manager(void* arg);//manager for user 49 | public: 50 | ThreadPool(unsigned int threadNum=10);//create threads 51 | ~ThreadPool();//destory pool 52 | void threadExit();// a no use funtion 53 | void addTask(Task task);//by this you can add task 54 | void endPool();//user delete the pool 55 | void getBusyAndTask(unsigned int* pthread,unsigned int* ptask);//get busy live and task num; 56 | inline void mutexLock()//user to lock ctrl 57 | { 58 | pthread_mutex_lock(&this->lockTask); 59 | } 60 | inline void mutexUnlock()//user to lock ctrl 61 | { 62 | pthread_mutex_unlock(&this->lockTask); 63 | } 64 | static pthread_t createPthread(void* arg,void* (*pfunc)(void*));//create a thread 65 | static inline void waitPthread(pthread_t thread,void** preturn=NULL)//wait the thread end 66 | { 67 | pthread_join(thread,preturn); 68 | } 69 | static void createDetachPthread(void* arg,void* (*pfunc)(void*));//create a ddetach thread 70 | }; 71 | /******************************** 72 | author:chenxuan 73 | date:2021/11/5 74 | funtion:server tcp ip 2.0 75 | *********************************/ 76 | class ServerPool:public ServerTcpIp 77 | { 78 | private: 79 | struct Argv{ 80 | ServerPool* pserver; 81 | void (*func)(ServerPool&,int); 82 | int soc; 83 | Argv() 84 | { 85 | pserver=NULL; 86 | soc=-1; 87 | func=NULL; 88 | } 89 | }; 90 | private: 91 | ThreadPool* pool; 92 | pthread_mutex_t mutex; 93 | unsigned int threadNum; 94 | bool isEpoll; 95 | private: 96 | inline static void sigCliDeal(int ) 97 | { 98 | while(waitpid(-1, NULL, WNOHANG)>0); 99 | } 100 | static void* worker(void* argc); 101 | public: 102 | ServerPool(unsigned short port,unsigned int threadNum=0):ServerTcpIp(port); 103 | ~ServerPool(); 104 | inline void mutexLock() 105 | { 106 | pthread_mutex_lock(&mutex); 107 | } 108 | inline void mutexUnlock() 109 | { 110 | pthread_mutex_unlock(&mutex); 111 | } 112 | bool mutexTryLock(); 113 | void threadModel(void (*pfunc)(ServerPool&,int)); 114 | void forkModel(void* pneed,void (*pfunc)(ServerPool&,int,void*)); 115 | void forkEpoll(unsigned int senBufChar,unsigned int recBufChar,void (*pfunc)(ServerPool::Thing,int,int,void*,void*,ServerPool&)); 116 | void epollThread(void (*pfunc)(ServerPool&,int)); 117 | inline bool threadDeleteSoc(int clisoc) 118 | { 119 | close(clisoc); 120 | if(isEpoll) 121 | epoll_ctl(epfd,clisoc,EPOLL_CTL_DEL,NULL); 122 | return this->deleteFd(clisoc); 123 | } 124 | }; 125 | } 126 | #endif 127 | -------------------------------------------------------------------------------- /old/lib/libhttp.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuan520/cppweb/38c2f7f20277789ea6bd2d125b2daf7b1fff4d73/old/lib/libhttp.a -------------------------------------------------------------------------------- /old/lib/libserver.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuan520/cppweb/38c2f7f20277789ea6bd2d125b2daf7b1fff4d73/old/lib/libserver.a -------------------------------------------------------------------------------- /old/lib/libsql.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuan520/cppweb/38c2f7f20277789ea6bd2d125b2daf7b1fff4d73/old/lib/libsql.a -------------------------------------------------------------------------------- /old/lib/libthreadpoll.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuan520/cppweb/38c2f7f20277789ea6bd2d125b2daf7b1fff4d73/old/lib/libthreadpoll.a -------------------------------------------------------------------------------- /old/lib/libthreadpool.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuan520/cppweb/38c2f7f20277789ea6bd2d125b2daf7b1fff4d73/old/lib/libthreadpool.a -------------------------------------------------------------------------------- /old/lib/thread.h: -------------------------------------------------------------------------------- 1 | #ifndef _THREAD_H_ 2 | #define _THREAD_H_ 3 | #include 4 | #include 5 | #include"server.h" 6 | /******************************** 7 | author:chenxuan 8 | date:2021/8/10 9 | funtion:class thread pool 10 | *********************************/ 11 | namespace cppweb{ 12 | 13 | class ThreadPool{ 14 | public://a struct for you to add task 15 | struct Task{ 16 | void* (*ptask)(void*); 17 | void* arg; 18 | }; 19 | private: 20 | std::queue thingWork;//a queue for struct task 21 | pthread_cond_t condition;//a condition mutex 22 | pthread_mutex_t lockPoll;//a lock to lock queue 23 | pthread_mutex_t lockTask;//a lock for user to ctrl 24 | pthread_mutex_t lockBusy;//a lock for busy thread 25 | pthread_t* thread;//an array for thread 26 | pthread_t threadManager;//thread for manager user to ctrl 27 | unsigned int liveThread;//num for live thread 28 | unsigned int busyThread;//num for busy thread 29 | bool isContinue;//if the pool is continue 30 | private: 31 | static void* worker(void* arg);//the worker for user 32 | static void* manager(void* arg);//manager for user 33 | public: 34 | ThreadPool(unsigned int threadNum=10);//create threads 35 | ~ThreadPool();//destory pool 36 | void threadExit();// a no use funtion 37 | void addTask(Task task);//by this you can add task 38 | void endPool();//user delete the pool 39 | void getBusyAndTask(unsigned int* pthread,unsigned int* ptask);//get busy live and task num; 40 | inline void mutexLock()//user to lock ctrl 41 | { 42 | pthread_mutex_lock(&this->lockTask); 43 | } 44 | inline void mutexUnlock()//user to lock ctrl 45 | { 46 | pthread_mutex_unlock(&this->lockTask); 47 | } 48 | static pthread_t createPthread(void* arg,void* (*pfunc)(void*));//create a thread 49 | static inline void waitPthread(pthread_t thread,void** preturn=NULL)//wait the thread end 50 | { 51 | pthread_join(thread,preturn); 52 | } 53 | static void createDetachPthread(void* arg,void* (*pfunc)(void*));//create a ddetach thread 54 | }; 55 | /******************************** 56 | author:chenxuan 57 | date:2021/11/5 58 | funtion:server tcp ip 2.0 59 | *********************************/ 60 | class ServerPool:public ServerTcpIp{ 61 | private: 62 | struct Argv{ 63 | ServerPool* pserver; 64 | void (*func)(ServerPool&,int); 65 | int soc; 66 | Argv() 67 | { 68 | pserver=NULL; 69 | soc=-1; 70 | func=NULL; 71 | } 72 | }; 73 | private: 74 | ThreadPool* pool; 75 | pthread_mutex_t mutex; 76 | unsigned int threadNum; 77 | bool isEpoll; 78 | private: 79 | static void sigCliDeal(int pid); 80 | static void* worker(void* argc); 81 | public: 82 | ServerPool(unsigned short port,unsigned int threadNum=0); 83 | ~ServerPool(); 84 | inline void mutexLock() 85 | { 86 | pthread_mutex_lock(&mutex); 87 | } 88 | inline void mutexUnlock() 89 | { 90 | pthread_mutex_unlock(&mutex); 91 | } 92 | bool mutexTryLock(); 93 | void forkModel(void* pneed,void (*pfunc)(ServerPool&,int,void*)); 94 | void forkEpoll(unsigned int senBufChar,unsigned int recBufChar,void (*pfunc)(ServerPool::Thing,int,int,void*,void*,ServerPool&)); 95 | void threadModel(void (*pfunc)(ServerPool&,int)); 96 | void epollThread(void (*pfunc)(ServerPool&,int)); 97 | inline bool threadDeleteSoc(int clisoc) 98 | { 99 | close(clisoc); 100 | return this->deleteFd(clisoc); 101 | } 102 | }; 103 | } 104 | #endif 105 | -------------------------------------------------------------------------------- /old/res/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 32 | 33 | 34 |
35 |
36 |
404 很抱歉,您查看的页面找不到了!
37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /old/res/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuan520/cppweb/38c2f7f20277789ea6bd2d125b2daf7b1fff4d73/old/res/favicon.ico -------------------------------------------------------------------------------- /old/res/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 服务器生成 10 | 11 | 131 | 132 | 133 | 134 | 135 |
136 | 137 |
138 |

配置填写

139 |

请填写以下内容,然后就可以自动生成服务器!

140 |
141 | 142 |
143 |
144 | 145 |
146 |
147 | 148 |
149 |
150 | 151 |
152 |
153 | 154 |
155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 |
165 | 166 |
167 |
168 | 169 | -------------------------------------------------------------------------------- /old/res/ini.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 32 | 33 | 34 |
35 |
36 |
恭喜!服务器配置成功

37 |
请在linux运行sudo ./main
38 |
39 |
40 | 41 | -------------------------------------------------------------------------------- /src/.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: -misc-definitions-in-headers 2 | -------------------------------------------------------------------------------- /src/cpp/dealask.cpp: -------------------------------------------------------------------------------- 1 | /******************************** 2 | author:chenxuan 3 | date:2021.7.5 4 | funtion:this cpp is for you to deal ask 5 | if you wang to change you web to a no-static 6 | *********************************/ 7 | #include"../hpp/dealask.h" 8 | #include "../hpp/cppweb.h" 9 | //#include"../hpp/sql.h" 10 | /******************************** 11 | author:chenxuan 12 | date:2021.7.5 13 | funtion:this function is to deal get you can 14 | add hpp and add funtion there 15 | *********************************/ 16 | bool DealAsk::dealGetAsk(ServerTcpIp& ,DealHttp& ,void* ,void*,int ) 17 | { 18 | return false; 19 | } 20 | /******************************** 21 | author:chenxuan 22 | date:2021.7.5 23 | funtion:deal post ask there 24 | *********************************/ 25 | bool DealAsk::dealPostAsk(ServerTcpIp& server,DealHttp& http,void* pget,void* sen,int soc) 26 | { 27 | return true; 28 | } 29 | void DealAsk::dealClientIn(ServerTcpIp& server,DealHttp& http,void* pget,void* sen,int soc) 30 | { 31 | return; 32 | } 33 | void DealAsk::dealClientOut(ServerTcpIp& server,DealHttp& http,void* pget,void* sen,int soc) 34 | { 35 | return; 36 | } 37 | -------------------------------------------------------------------------------- /src/cpp/mainold.cpp: -------------------------------------------------------------------------------- 1 | /******************************** 2 | author:chenxuan 3 | date:2021.7.5 4 | funtion:this is main cpp for static web 5 | *********************************/ 6 | //#include"../hpp/sql.h" 7 | #include "../hpp/cppweb.h" 8 | #include"../hpp/dealask.h" 9 | #include 10 | #include 11 | #include 12 | using namespace cppweb; 13 | char indexName[100]="index.html"; 14 | int memory=0; 15 | /******************************** 16 | author:chenxuan 17 | date:2021.7.5 18 | funtion:main function to deal ask 19 | *********************************/ 20 | int funcTwo(ServerTcpIp::Thing thing,int num,int,void* pget,void* sen,ServerTcpIp& server)//main deal func 21 | { 22 | char ask[200]={0}; 23 | static DealHttp http; 24 | DealAsk dealAsk; 25 | int len=0; 26 | int flag=0; 27 | if(sen==NULL) 28 | return -1; 29 | memset(sen,0,sizeof(char)*memory*1024*1024); 30 | // if(false==DealAttack::dealAttack(thing,num,200)) 31 | // { 32 | // DealAttack::attackLog(port,server.getPeerIp(num,&port),"./rec/attackLog.txt"); 33 | // server.disconnectSocketEpoll(num); 34 | // return 0; 35 | // } 36 | if(thing==ServerTcpIp::CPPOUT) 37 | dealAsk.dealClientOut(server,http,pget,sen,num); 38 | if(thing==ServerTcpIp::CPPIN) 39 | dealAsk.dealClientIn(server,http,pget,sen,num); 40 | if(thing==ServerTcpIp::CPPOUT) 41 | { 42 | if(strstr((char*)pget,"POST")!=NULL) 43 | { 44 | if(false==dealAsk.dealPostAsk(server,http,pget,sen,num)) 45 | return 0; 46 | } 47 | else if(strstr((char*)pget,"GET")!=NULL) 48 | { 49 | printf("http:%s\n",http.analysisHttpAsk(pget)); 50 | strcpy(ask,http.analysisHttpAsk(pget)); 51 | if(false==dealAsk.dealGetAsk(server,http,pget,sen,num)) 52 | { 53 | flag=http.autoAnalysisGet((char*)pget,(char*)sen,sizeof(char)*memory*1024*1024,indexName,&len); 54 | if(0==flag) 55 | printf("some thing wrong %s\n",(char*)sen); 56 | else if(flag==1) 57 | printf("create auto success\n"); 58 | else if(flag==2) 59 | { 60 | FILE* fp=fopen("wrong.txt","a+"); 61 | if(fp==NULL) 62 | fp=fopen("wrong.txt","w+"); 63 | if(fp==NULL) 64 | return 0; 65 | fprintf(fp,"can not open file %s\n",ask); 66 | printf("cannot open file %s\n",ask); 67 | fclose(fp); 68 | } 69 | } 70 | } 71 | else 72 | return 0; 73 | if(0>=server.sendSocket(num,sen,len)) 74 | printf("send wrong\n"); 75 | else 76 | printf("send success\n"); 77 | } 78 | return 0; 79 | } 80 | /******************************** 81 | author:chenxuan 82 | date:2021.7.5 83 | funtion:if no argc an file use it to init 84 | *********************************/ 85 | void chooseModel(unsigned int* port,bool* pflag) 86 | { 87 | char temp[10]={0}; 88 | printf("please input the import(default 80):"); 89 | scanf("%u",port); 90 | printf("please input index.html(default index.html):"); 91 | scanf("%s",indexName); 92 | printf("please input if run in background(default no)y/n:"); 93 | fflush(stdin); 94 | scanf("%s",temp); 95 | printf("please input memory(M):"); 96 | fflush(stdin); 97 | scanf("%d",&memory); 98 | if(strchr(temp,'y')!=NULL) 99 | *pflag=true; 100 | else 101 | *pflag=false; 102 | FILE* fp=fopen("my.ini","r+"); 103 | if(fp!=NULL) 104 | { 105 | fclose(fp); 106 | return; 107 | } 108 | fp=fopen("my.ini","w+"); 109 | if(fp==NULL) 110 | return; 111 | fprintf(fp,"%u %s %d %s",*port,indexName,memory,temp); 112 | fclose(fp); 113 | } 114 | /******************************** 115 | author:chenxuan 116 | date:2021.7.5 117 | funtion:from file init server 118 | *********************************/ 119 | void ifChoose(bool* pb,unsigned int* pport,bool* is_back) 120 | { 121 | char temp[10]={0}; 122 | FILE* fp=fopen("my.ini","r+"); 123 | if(fp==NULL) 124 | { 125 | *pb=false; 126 | return; 127 | } 128 | if(fscanf(fp,"%u",pport)!=1) 129 | { 130 | *pb=false; 131 | printf("port=%u\n",*pport); 132 | return; 133 | } 134 | if(fscanf(fp,"%s",indexName)!=1) 135 | { 136 | *pb=false; 137 | printf("name:%s\n",indexName); 138 | return; 139 | } 140 | if(fscanf(fp,"%d",&memory)!=1) 141 | { 142 | *pb=false; 143 | printf("memory=%d\n",memory); 144 | return; 145 | } 146 | if(fscanf(fp,"%s",temp)!=1) 147 | { 148 | *pb=false; 149 | printf("is back wrong\n"); 150 | return; 151 | } 152 | if(strchr(temp,'y')!=NULL) 153 | *is_back=true; 154 | else 155 | *is_back=false; 156 | *pb=true; 157 | fclose(fp); 158 | return; 159 | } 160 | /******************************** 161 | author:chenxuan 162 | date:2021.7.5 163 | funtion:from argv to init server 164 | *********************************/ 165 | bool ifArgc(int argc,char** argv,bool* pis_back,unsigned int* pport) 166 | { 167 | if(argc!=5) 168 | return false; 169 | if(sscanf(argv[1],"%d",pport)!=1) 170 | { 171 | printf("init wrong\n"); 172 | return false; 173 | } 174 | sscanf(argv[2],"%s",indexName); 175 | if(sscanf(argv[3],"%d",&memory)!=1) 176 | { 177 | printf("memory wrong\n"); 178 | return false; 179 | } 180 | if(strchr(argv[4],'y')!=NULL) 181 | *pis_back=true; 182 | return true; 183 | } 184 | /******************************** 185 | author:chenxuan 186 | date:2021.7.5 187 | funtion:server begin 188 | *********************************/ 189 | void serverHttp(int argc,char** argv) 190 | { 191 | unsigned int port=80; 192 | bool is_back=false,is_choose=false; 193 | ifChoose(&is_choose,&port,&is_back); 194 | if(ifArgc(argc,argv,&is_back,&port)==false&&is_choose==false) 195 | chooseModel(&port,&is_back); 196 | if(is_back) 197 | { 198 | int pid=0; 199 | if((pid=fork())!=0) 200 | { 201 | printf("pid=%d\n",pid); 202 | return; 203 | } 204 | } 205 | ServerTcpIp server((unsigned short)port,100); 206 | char get[2048]={0}; 207 | char* sen=(char*)malloc(sizeof(char)*memory*1024*1024); 208 | if(sen==NULL) 209 | printf("memory wrong\n"); 210 | // HttpServer server(5200); 211 | // server.run(1,"./index.html"); 212 | if(false==server.bondhost()) 213 | { 214 | printf("bound wrong\n"); 215 | exit(0); 216 | } 217 | if(false==server.setlisten()) 218 | exit(0); 219 | printf("the server is ok\n"); 220 | while(1) 221 | if(false==server.epollModel(get,2048,sen,funcTwo)) 222 | break; 223 | free(sen); 224 | } 225 | int main(int argc, char** argv) 226 | { 227 | serverHttp(argc,argv); 228 | return 0; 229 | } 230 | -------------------------------------------------------------------------------- /src/cpp/redis.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | /******************************** 5 | author:chenxuan 6 | date:2021/8/15 7 | funtion:class for deal Redis ask 8 | *********************************/ 9 | class RedisDeal{ 10 | private: 11 | redisContext* redis; 12 | redisReply* reply; 13 | char command[256]; 14 | public: 15 | RedisDeal(const char* ip,unsigned port ) 16 | { 17 | reply=NULL; 18 | redis=NULL; 19 | redis=redisConnect(ip,port); 20 | memset(command,0,256); 21 | if(redis==NULL||redis->err) 22 | throw redis->errstr; 23 | } 24 | ~RedisDeal() 25 | { 26 | redisFree(redis); 27 | if(reply!=NULL) 28 | freeReplyObject(reply); 29 | } 30 | redisReply* doCommand(const char* command) 31 | { 32 | if(reply!=NULL) 33 | freeReplyObject(reply); 34 | reply=(redisReply*)redisCommand(redis,command); 35 | return reply; 36 | } 37 | const char* get(const char* name) 38 | { 39 | if(strlen(name)>200) 40 | return NULL; 41 | memset(command,0,256); 42 | sprintf(command,"get %s",name); 43 | if(reply!=NULL) 44 | freeReplyObject(reply); 45 | reply=(redisReply*)redisCommand(redis,command); 46 | if(reply->type==REDIS_REPLY_ERROR) 47 | return NULL; 48 | return reply->str; 49 | } 50 | const char* set(const char* name,const char* value) 51 | { 52 | if(strlen(name)+strlen(value)>230) 53 | return NULL; 54 | memset(command,0,256); 55 | sprintf(command,"set %s %s",name,value); 56 | if(reply!=NULL) 57 | freeReplyObject(reply); 58 | reply=(redisReply*)redisCommand(redis,command); 59 | if(reply->type==REDIS_REPLY_ERROR) 60 | return NULL; 61 | return reply->str; 62 | } 63 | const char* del(const char* name) 64 | { 65 | if(strlen(name)>230) 66 | return NULL; 67 | memset(command,0,256); 68 | sprintf(command,"del %s",name); 69 | if(reply!=NULL) 70 | freeReplyObject(reply); 71 | reply=(redisReply*)redisCommand(redis,command); 72 | if(reply->type==REDIS_REPLY_ERROR) 73 | return NULL; 74 | return reply->str; 75 | } 76 | int strLen(const char* name) 77 | { 78 | if(strlen(name)>230) 79 | return -1; 80 | memset(command,0,256); 81 | sprintf(command,"strlen %s",name); 82 | if(reply!=NULL) 83 | freeReplyObject(reply); 84 | reply=(redisReply*)redisCommand(redis,command); 85 | if(reply->type!=REDIS_REPLY_INTEGER) 86 | return -1; 87 | return reply->integer; 88 | } 89 | }; 90 | int main() 91 | { 92 | RedisDeal redis("127.0.0.1",6379); 93 | redis.set("num","100"); 94 | 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /src/cpp/sql.cpp: -------------------------------------------------------------------------------- 1 | #include "../hpp/sql.h" 2 | #include 3 | #include 4 | using namespace std; 5 | MySql::MySql(const char* ipOrHostName,const char* user,const char* passwd,const char* dataBaseName) 6 | { 7 | this->results=NULL; 8 | this->mysql=mysql_init(NULL); 9 | if(NULL==mysql_real_connect(this->mysql,ipOrHostName,user,passwd,dataBaseName,0,NULL,0)) 10 | { 11 | cerr<mysql)<~MySql(); 13 | throw; 14 | } 15 | } 16 | MySql::~MySql() 17 | { 18 | if(this->results!=NULL) 19 | mysql_free_result(this->results); 20 | mysql_close(mysql); 21 | } 22 | int MySql::MySqlSelectQuery(const char* sql) 23 | { 24 | if(this->results!=NULL) 25 | mysql_free_result(this->results); 26 | int temp=mysql_query(this->mysql,sql); 27 | if(temp!=0) 28 | { 29 | cerr<mysql)<results=mysql_store_result(mysql); 33 | if(results==NULL) 34 | { 35 | cerr<mysql)<results); 39 | } 40 | bool MySql::MySqlOtherQuery(const char* sql) 41 | { 42 | int temp=mysql_query(this->mysql,sql); 43 | if(temp!=0) 44 | { 45 | cerr<mysql)<results==NULL) 53 | return NULL; 54 | return mysql_fetch_row(results); 55 | } 56 | 57 | -------------------------------------------------------------------------------- /src/example/README.md: -------------------------------------------------------------------------------- 1 | ## easy-http-server 2 | 3 | - 使用框架搭建一个简单的静态http服务器 4 | 5 | ## ranking-list 6 | 7 | - 使用框架搭建分数排名系统。 8 | 9 | ## route-use 10 | 11 | - 路由系统的使用样例 12 | 13 | ## set-cookie 14 | 15 | - 框架内设置cookie样例 16 | 17 | ## static-file 18 | 19 | - 加载静态文件样例,替换路由 20 | 21 | ## upload-file 22 | 23 | - 上传文件的样例 24 | 25 | ## delete-path 26 | 27 | - 删除需要排除的路径 28 | 29 | ## set-cookie 30 | 31 | - 设置获取cookie 32 | 33 | ## thread-model 34 | 35 | - 使用ServerPool 36 | 37 | ## chat-axios 38 | 39 | - 和前端axios交互 40 | 41 | ## use-cppweb 42 | 43 | - cppweb库使用 44 | 45 | ## strcut-datagram 46 | 47 | - 构建发送报文 48 | 49 | ## request-struct 50 | 51 | - 获取请求报文 52 | 53 | ## middware-use 54 | 55 | - 设置中间件 56 | 57 | ## ssl-https 58 | 59 | - 设置https服务器 60 | 61 | ## log-setting 62 | 63 | - 设置日志系统 64 | 65 | ## cli-ask 66 | 67 | - 客户端类的使用 68 | 69 | ## online-disk 70 | 71 | - 一个在线网盘系统 -------------------------------------------------------------------------------- /src/example/api-req/config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../../hpp/cppweb.h" 4 | using namespace std; 5 | using namespace cppweb; 6 | class Config{ 7 | private: 8 | Json json; 9 | public: 10 | struct Host{ 11 | string ip; 12 | unsigned port; 13 | }; 14 | const char* error; 15 | Host host; 16 | DealHttp::Request req; 17 | string body; 18 | Config(string configFile){ 19 | error=NULL; 20 | auto text=FileGet::getFileString(configFile.c_str()); 21 | if(text.size()==0){ 22 | error="file size wrong"; 23 | return; 24 | } 25 | auto flag=json.analyseText(text.c_str()); 26 | if(flag==false){ 27 | error=json.lastError(); 28 | return; 29 | } 30 | auto root=json.getRootObj(); 31 | if(root["host"]["ip"]!=Json::npos){ 32 | host.ip=root["host"]["ip"].strVal; 33 | char temp[32]={0}; 34 | if(false==ClientTcpIp::getDnsIp(host.ip.c_str(),temp,32)){ 35 | error="dns wrong"; 36 | return; 37 | } 38 | host.ip=temp; 39 | }else{ 40 | error="ip wrong"; 41 | return; 42 | } 43 | if(root["host"]["port"]!=Json::npos){ 44 | host.port=root["host"]["port"].intVal; 45 | }else{ 46 | error="port wrong"; 47 | return; 48 | } 49 | if(root["req"]["path"]!=Json::npos){ 50 | req.askPath=root["req"]["path"].strVal; 51 | }else{ 52 | error="path wrong"; 53 | return; 54 | } 55 | if(root["req"]["method"]!=Json::npos){ 56 | req.method=root["req"]["method"].strVal; 57 | }else{ 58 | error="method wrong"; 59 | return; 60 | } 61 | if(root["req"]["version"]!=Json::npos){ 62 | req.version=root["req"]["version"].strVal; 63 | } 64 | if(root["req"]["head"]!=Json::npos){ 65 | auto now=root["req"]["head"].nextObj; 66 | while(now!=NULL){ 67 | req.head.insert({now->key,now->strVal}); 68 | now=now->nextObj; 69 | } 70 | if(req.head.find("Host")==req.head.end()){ 71 | req.head.insert({"Host",root["host"]["ip"].strVal}); 72 | } 73 | }else{ 74 | error="head wrong"; 75 | return; 76 | } 77 | if(root["req"]["body"]!=Json::npos){ 78 | req.body=root["req"]["body"].excapeChar().strVal.c_str(); 79 | }else if(root["req"]["body_file"]!=Json::npos){ 80 | body=FileGet::getFileString(root["req"]["body_file"].strVal.c_str()); 81 | req.body=body.c_str(); 82 | }else{ 83 | error="body wrong"; 84 | return; 85 | } 86 | } 87 | }; 88 | -------------------------------------------------------------------------------- /src/example/api-req/config.json: -------------------------------------------------------------------------------- 1 | { 2 | //file to create request 3 | "host":{ 4 | //ip can be host name or ip name 5 | "ip":"127.0.0.1", 6 | "port":5200 7 | }, 8 | "req":{ 9 | "method":"GET", 10 | "path":"/", 11 | "version":"HTTP/1.1", 12 | "head":{ 13 | "Content-Type":"application/json;charset=utf-8", 14 | "X-Authorization":"token:qgemv4jr1y38jyq6vhvi", 15 | "Connection":"keep-alive" 16 | }, 17 | //if body is long,can change body to body_file to load file path 18 | //such as "body_file":"./config.json" 19 | "body":"{\"trans_type\":\"en2zh\",\"source\":\"hello\"}" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/example/api-req/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define CPPWEB_OPENSSL 3 | #include "../../hpp/cppweb.h" 4 | #include "../../hpp/argc.h" 5 | #include "config.h" 6 | using namespace std; 7 | using namespace cppweb; 8 | int _main(ArgcDeal& app) 9 | { 10 | auto fileName=app.getVari("config"); 11 | if(fileName.size()==0){ 12 | fileName="./config.json"; 13 | } 14 | Config config(fileName); 15 | if(config.error!=NULL){ 16 | printf("config wrong %s\n",config.error); 17 | return 0; 18 | } 19 | auto buffer=config.req.createAskRequest(); 20 | if(config.req.error!=NULL){ 21 | printf("req create wrong\n"); 22 | return 0; 23 | } 24 | if(app.getOption("v")){ 25 | cout<<"request:"< 2 | #include 3 | #include "../../hpp/cppweb.h" 4 | using namespace std; 5 | using namespace cppweb; 6 | void root(HttpServer&,DealHttp& http,int) 7 | { 8 | Json json{ 9 | {"status","ok"} 10 | }; 11 | http.gram.head["Access-Control-Allow-Origin"]="*"; 12 | http.gram.body=json(); 13 | } 14 | int main() 15 | { 16 | HttpServer server(5200,true); 17 | server.all("/root",root); 18 | server.get("/stop",[](HttpServer& server,DealHttp&,int){ 19 | server.stopServer(); 20 | }); 21 | server.run("b.html"); 22 | printf("%s",server.lastError()); 23 | return 0; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/example/chat-axios/makefile: -------------------------------------------------------------------------------- 1 | all:main 2 | main:main.cpp 3 | g++ -g main.cpp -o main -lpthread 4 | 5 | -------------------------------------------------------------------------------- /src/example/cli-ask/dict.cpp: -------------------------------------------------------------------------------- 1 | #define CPPWEB_OPENSSL 2 | #include "../../hpp/cppweb.h" 3 | using namespace std; 4 | using namespace cppweb; 5 | void dict(const char* str) 6 | { 7 | char ip[32]={0}; 8 | auto serverIP=ClientTcpIp::getDnsIp("api.interpreter.caiyunai.com"); 9 | if(serverIP=="") 10 | { 11 | printf("dns wrong\n"); 12 | return ; 13 | } 14 | ClientTcpIp client(serverIP,443); 15 | auto flag=client.tryConnectSSL(); 16 | if(!flag) 17 | { 18 | printf("connect %s wrong\n",ip); 19 | return; 20 | } 21 | DealHttp::Request req; 22 | Json json={ 23 | {"trans_type","en2zh"}, 24 | {"source",str} 25 | }; 26 | req.method="POST"; 27 | req.askPath="/v1/dict"; 28 | req.head["Host"]="api.interpreter.caiyunai.com"; 29 | req.head["Content-Type"]="application/json;charset=utf-8"; 30 | req.head["X-Authorization"]="token:qgemv4jr1y38jyq6vhvi"; 31 | req.head["Connection"]="keep-alive"; 32 | req.body=json(); 33 | auto buffer=req.createAskRequest(); 34 | if(0>=client.sendHost(buffer.c_str(),buffer.size())) 35 | { 36 | printf("send wrong\n"); 37 | return ; 38 | } 39 | buffer.clear(); 40 | if(0>=HttpApi::getCompleteHtmlSSL(buffer,client.getSSL())) 41 | { 42 | printf("recv wrong\n"); 43 | return; 44 | } 45 | req.analysisRequest(buffer.c_str(),buffer.size()); 46 | auto body=req.hexStrToUtf8(req.body); 47 | flag=json.analyseText(body.c_str()); 48 | if(flag==false) 49 | { 50 | printf("json error:%s\n",json.lastError()); 51 | return; 52 | } 53 | auto root=json.getRootObj(); 54 | printf("English:\n%s\nChinese:\n",str); 55 | if(root["dictionary"]["explanations"]!=Json::npos) 56 | { 57 | auto now=root["dictionary"]["explanations"]; 58 | for(auto strNow:now.arr) 59 | printf("%s\n",strNow->strVal.c_str()); 60 | } 61 | else 62 | printf("message not found\n"); 63 | return; 64 | } 65 | int main(int argc,char** argv) 66 | { 67 | if(argc!=2) 68 | { 69 | printf("argv wrong,please input the url to argv\n"); 70 | exit(0); 71 | } 72 | dict(argv[1]); 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /src/example/cli-ask/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define CPPWEB_OPENSSL 3 | #include "../../hpp/cppweb.h" 4 | using namespace std; 5 | using namespace cppweb; 6 | void wget(const char* str) 7 | { 8 | char ip[32]={0},topUrl[128]={0},endUrl[128]={0}; 9 | unsigned port=5200; 10 | bool isHttps=false; 11 | DealHttp::dealUrl(str,topUrl,endUrl,128,128); 12 | if(strstr(str,"127.0.0.1")!=NULL) 13 | { 14 | sscanf(topUrl,"%[^:]:%u",ip,&port); 15 | if(strstr(str,"https")!=NULL) 16 | isHttps=true; 17 | } 18 | else 19 | { 20 | ClientTcpIp::getDnsIp(topUrl,ip,32); 21 | if(strstr(str,"https")!=NULL) 22 | { 23 | isHttps=true; 24 | port=443; 25 | } 26 | else 27 | port=80; 28 | } 29 | if(strlen(ip)==0) 30 | { 31 | printf("dns ip wrong\n"); 32 | exit(0); 33 | } 34 | printf("ip:%s\n",ip); 35 | printf("port:%u\n",port); 36 | ClientTcpIp client(ip,port); 37 | if(client.lastError()!=NULL) 38 | { 39 | printf("error%s\n;",client.lastError()); 40 | exit(0); 41 | } 42 | DealHttp http; 43 | DealHttp::Request req; 44 | req.head.insert(pair{"Host",topUrl}); 45 | req.askPath=endUrl; 46 | req.method="GET"; 47 | req.version="HTTP/1.1"; 48 | char buffer[500]={0}; 49 | string rec; 50 | http.createAskRequest(req,buffer,500); 51 | printf("buffer:\n%s\n",buffer); 52 | if(!isHttps) 53 | { 54 | if(false==client.tryConnect()) 55 | { 56 | printf("connect wrong\n"); 57 | exit(0); 58 | } 59 | if(0>client.sendHost(buffer,strlen(buffer))) 60 | { 61 | printf("%d",errno); 62 | printf("send wrong"); 63 | exit(0); 64 | } 65 | auto soc=client.getSocket(); 66 | HttpApi::getCompleteHtml(rec,soc); 67 | } 68 | else 69 | { 70 | if(false==client.tryConnectSSL()) 71 | { 72 | printf("connect wrong\n"); 73 | exit(0); 74 | } 75 | if(0>client.sendHost(buffer,strlen(buffer))) 76 | { 77 | printf("%d",errno); 78 | printf("send wrong"); 79 | exit(0); 80 | } 81 | auto ssl=client.getSSL(); 82 | HttpApi::getCompleteHtmlSSL(rec,ssl); 83 | } 84 | cout< 2 | #include "../../hpp/cppweb.h" 3 | using namespace cppweb; 4 | struct Temp{ 5 | int soc; 6 | char cookie[128]; 7 | }; 8 | struct Temp1{ 9 | int soc; 10 | std::string cookie; 11 | }; 12 | void login(HttpServer&,DealHttp& http,int soc){ 13 | auto flag=http.req.getCookie("key",http.info.recText); 14 | if(flag.size()>0){ 15 | Temp temp={soc,{0}}; 16 | Temp1 temp1={soc,flag}; 17 | strncpy(temp.cookie,flag.c_str(),128); 18 | http.setVar("cookie",temp); 19 | http.setVar("cookie1",temp1,true); 20 | http.setVar("id",soc); 21 | http.info.isContinue=true; 22 | }else{ 23 | http.gram.json(DealHttp::STATUSOK,Json::createJson({{"status","find wrong"}})); 24 | } 25 | } 26 | void message(HttpServer&,DealHttp& http,int){ 27 | Temp* pstr=(Temp*)http.getVar("cookie"); 28 | Temp1* pstr1=(Temp1*)http.getVar("cookie1"); 29 | if(pstr==NULL||pstr1==NULL){ 30 | http.gram.json(http.STATUSOK,"{\"status\",\"wrong\"}"); 31 | return; 32 | } 33 | int* pid=(int*)http.getVar("id"); 34 | if(pstr==NULL){ 35 | http.gram.json(DealHttp::STATUSNOFOUND,Json::createJson({{"status","wrong"}})); 36 | }else{ 37 | http.gram.json(DealHttp::STATUSOK,Json::createJson({ 38 | {"cookie",pstr->cookie},{"soc",pstr->soc},{"id",*pid}, 39 | {"cookie1",pstr1->cookie},{"soc1",pstr1->soc}, 40 | })); 41 | } 42 | http.deleteVar("cookie1"); 43 | } 44 | void setLogin(HttpServer&,DealHttp& http,int){ 45 | auto flag=http.req.getCookie("key",http.info.recText); 46 | if(flag.size()>0){ 47 | http.gram.txt(DealHttp::STATUSOK,"ok"); 48 | return; 49 | } 50 | cppweb::KeyMap key; 51 | http.req.routePairing("/cookie/:id",key,(char*)http.info.recText); 52 | http.gram.cookie["key"]=http.designCookie(key["id"].c_str(),10,"/"); 53 | http.gram.json(DealHttp::STATUSOK,Json::createJson({{"status","ok"},{"id",key["id"]}})); 54 | } 55 | int main() 56 | { 57 | HttpServer server(5200,true);//input the port bound 58 | if(server.lastError()!=NULL) 59 | { 60 | std::cout< 2 | 3 | 4 | 32 | 33 | 34 |
35 |
36 |
恭喜!服务器运行成功

37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /src/example/delete-path/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../hpp/cppweb.h" 3 | using namespace std; 4 | using namespace cppweb; 5 | int main() 6 | { 7 | HttpServer server(5200,true); 8 | server.deletePath("test"); 9 | server.run("./index.html"); 10 | if(NULL!=server.lastError()) 11 | { 12 | printf("%s\n",server.lastError()); 13 | return -1; 14 | } 15 | return 0; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/example/delete-path/makefile: -------------------------------------------------------------------------------- 1 | all:main 2 | main:main.cpp ../../hpp/cppweb.h 3 | g++ -g main.cpp -o main -lpthread 4 | 5 | -------------------------------------------------------------------------------- /src/example/delete-path/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 32 | 33 | 34 |
35 |
36 |
恭喜!服务器运行成功

37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /src/example/easy-http-server/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 32 | 33 | 34 |
35 |
36 |
恭喜!服务器运行成功

37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /src/example/easy-http-server/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../hpp/cppweb.h" 3 | using namespace cppweb; 4 | int main() 5 | { 6 | HttpServer server(5200);//input the port bound 7 | server.changeSetting(false,false);//close long connect and do not print message 8 | if(server.lastError()!=NULL) 9 | { 10 | std::cout< 2 | #include "../../hpp/cppweb.h" 3 | using namespace cppweb; 4 | using namespace std; 5 | int main() 6 | { 7 | /* ProcessCtrl::backGround(); */ 8 | HttpServer server(5200,true);//input the port bound 9 | if(server.lastError()!=NULL) 10 | { 11 | std::cout< route; 16 | http.req.routePairing("/:route",route,(char*)ser.recText(http)); 17 | auto result="https://chenxuanweb.top/"+route["route"]; 18 | http.gram.redirect(result); 19 | }); 20 | server.run(); 21 | return 0; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/example/gram-redirect/makefile: -------------------------------------------------------------------------------- 1 | all:main 2 | main:main.cpp ../../hpp/cppweb.h 3 | g++ main.cpp -o main -lpthread 4 | 5 | -------------------------------------------------------------------------------- /src/example/log-setting/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 32 | 33 | 34 |
35 |
36 |
恭喜!服务器运行成功

37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /src/example/log-setting/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../hpp/cppweb.h" 3 | using namespace std; 4 | using namespace cppweb; 5 | int main() 6 | { 7 | HttpServer server(5200,true); 8 | server.setLog(LogSystem::recordRequest); 9 | server.get("/stop",[](HttpServer& server,DealHttp&,int){ 10 | server.stopServer(); 11 | }); 12 | server.run("index.html"); 13 | return 0; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/example/log-setting/makefile: -------------------------------------------------------------------------------- 1 | all:main 2 | main:main.cpp ../../hpp/cppweb.h 3 | g++ -g main.cpp -o main -lpthread 4 | 5 | -------------------------------------------------------------------------------- /src/example/middleware-use/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 32 | 33 | 34 |
35 |
36 |
恭喜!服务器运行成功

37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /src/example/middleware-use/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../hpp/cppweb.h" 3 | using namespace std; 4 | using namespace cppweb; 5 | void pfunc(HttpServer&,DealHttp& http,int) 6 | { 7 | http.head["hahah"]="en"; 8 | http.info.isContinue=true; 9 | /* char temp[1000]={0}; */ 10 | /* Json json; */ 11 | /* char* text=json.createObject(200); */ 12 | /* json.addKeyVal(text,Json::STRING,"hah","oko"); */ 13 | /* gram.body=text; */ 14 | /* gram.fileLen=strlen(text); */ 15 | /* gram.typeFile=DealHttp::JSON; */ 16 | /* http.createDatagram(gram,temp,1000); */ 17 | /* server.httpSend(soc,temp,strlen(temp)); */ 18 | } 19 | void pfunc1(HttpServer&,DealHttp& http,int){ 20 | http.head["ok"]="lalala"; 21 | http.info.isContinue=true; 22 | } 23 | int main() 24 | { 25 | HttpServer server(5200,true); 26 | server.setMiddleware(pfunc); 27 | server.setMiddleware(pfunc1); 28 | server.get("/root",[](HttpServer&,DealHttp& http,int){ 29 | http.gram.body="text"; 30 | }); 31 | server.run("./index.html"); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /src/example/middleware-use/makefile: -------------------------------------------------------------------------------- 1 | all:main 2 | main:main.cpp ../../hpp/cppweb.h 3 | g++ main.cpp -o main -lpthread 4 | -------------------------------------------------------------------------------- /src/example/old-version/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 32 | 33 | 34 |
35 |
36 |
恭喜!服务器运行成功

37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /src/example/old-version/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../hpp/cppweb.h" 3 | using namespace cppweb; 4 | char* buffer=NULL; 5 | int func(ServerTcpIp::Thing thing,int soc,ServerTcpIp& server,void*) 6 | { 7 | if(thing==ServerTcpIp::CPPIN) 8 | { 9 | printf("%d in\n",soc); 10 | return 0; 11 | } 12 | memset(buffer,0,1000000); 13 | int len=server.receiveSocket(soc,buffer,1000000); 14 | if(len<=0) 15 | return soc; 16 | DealHttp http; 17 | int flag=http.autoAnalysisGet(buffer,buffer,1000000,"./index.html",&len); 18 | if(flag==2||flag==0) 19 | printf("ask:%s\n",buffer); 20 | server.sendSocket(soc,buffer,len); 21 | return 0; 22 | } 23 | int main() 24 | { 25 | ServerTcpIp server(5200); 26 | buffer=(char*)malloc(sizeof(char)*1000000); 27 | if(buffer==NULL) 28 | { 29 | printf("buffer wrong\n"); 30 | return -1; 31 | } 32 | if(false==server.bondhost()) 33 | { 34 | printf("bound wrong\n"); 35 | return -1; 36 | } 37 | if(false==server.setlisten()) 38 | { 39 | printf("%s\n",server.lastError()); 40 | return -1; 41 | } 42 | while(1) 43 | server.selectModel(func,NULL); 44 | return 0; 45 | } 46 | 47 | -------------------------------------------------------------------------------- /src/example/old-version/makefile: -------------------------------------------------------------------------------- 1 | all:main 2 | main:main.cpp ../../hpp/cppweb.h 3 | g++ -g main.cpp -o main -lpthread 4 | 5 | -------------------------------------------------------------------------------- /src/example/online-disk/config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../hpp/cppweb.h" 3 | #include "../../hpp/argc.h" 4 | using namespace cppweb; 5 | struct _Config{ 6 | std::string passwd; 7 | std::string storePath; 8 | std::string logPath; 9 | bool isLog; 10 | bool isVerify; 11 | int port; 12 | int tokenTime; 13 | _Config():passwd("123456"),storePath("./template"),\ 14 | isLog(false),isVerify(true),port(5200),tokenTime(120){}; 15 | }_config; 16 | bool configServer(const char* configPath) 17 | { 18 | if(configPath==NULL) 19 | return false; 20 | auto strGet=FileGet::getFileString(configPath); 21 | Json json(strGet.c_str()); 22 | auto root=json.getRootObj(); 23 | if(root["log"]!=Json::npos) 24 | _config.isLog=root["log"].boolVal; 25 | if(root["port"]!=Json::npos) 26 | _config.port=root["port"].intVal; 27 | if(root["passwd"]!=Json::npos) 28 | _config.passwd=root["passwd"].strVal; 29 | if(root["log path"]!=Json::npos) 30 | _config.logPath=root["log path"].strVal; 31 | if(root["store"]!=Json::npos) 32 | _config.storePath=root["store"].strVal; 33 | if(root["token time"]!=Json::npos) 34 | _config.tokenTime=root["token time"].intVal; 35 | if(root["verify"]!=Json::npos) 36 | _config.isVerify=root["verify"].boolVal; 37 | if(_config.storePath.size()!=0) 38 | { 39 | auto flag=chdir(_config.storePath.c_str()); 40 | if(flag!=0) 41 | { 42 | perror("chdir wrong"); 43 | exit(0); 44 | } 45 | } 46 | if(_config.logPath.size()!=0&&_config.isLog) 47 | LogSystem::defaultName=_config.logPath.c_str(); 48 | return true; 49 | } 50 | -------------------------------------------------------------------------------- /src/example/online-disk/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "port":5200, 3 | "log":false, 4 | "log path":"./access.log", 5 | "token time":120, 6 | "store":"./template", 7 | "verify":true, 8 | "passwd":"123456" 9 | } 10 | -------------------------------------------------------------------------------- /src/example/online-disk/edit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Edit file 8 | 124 | 125 | 126 |
127 |
128 |

edit online

129 |

commit button is save the edit text
update button is get the lastest file message
back button is back to home

130 |
131 | 132 | 133 | 134 | 135 |
136 |
137 |
138 | 139 | 168 | 169 | -------------------------------------------------------------------------------- /src/example/online-disk/jump.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | opertor ok 7 | Login 8 | 68 | 69 | 70 |
71 |
72 |

操作成功!
页面在3s后自动跳转


73 | 74 |
75 |
76 | 77 | 84 | -------------------------------------------------------------------------------- /src/example/online-disk/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Login 7 | 171 | 172 | 173 |
174 |
175 |
176 |

请输入密码


177 |
178 | 179 |
180 |
181 |
182 | 183 | 184 | -------------------------------------------------------------------------------- /src/example/online-disk/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../hpp/cppweb.h" 3 | #include "./config.h" 4 | #include "./route.h" 5 | using namespace cppweb; 6 | int main(int argc,char** argv) 7 | { 8 | ArgcDeal arg(argc,argv); 9 | arg.app.name="online-disk"; 10 | arg.app.usage="store file online and easily to get web link"; 11 | arg.app.version="v1.1"; 12 | arg.app.pfunc=_main; 13 | arg.setOption("d","run app in background"); 14 | arg.setOption("g","restart if the app fall auto"); 15 | return arg.run(); 16 | } 17 | -------------------------------------------------------------------------------- /src/example/online-disk/makefile: -------------------------------------------------------------------------------- 1 | all:main 2 | main:main.cpp ./route.h ./config.h ../../hpp/cppweb.h 3 | g++ -g main.cpp -o main -lpthread 4 | 5 | -------------------------------------------------------------------------------- /src/example/online-disk/template/readme.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Welcome to chenxuan online disk ! 5 | 12 | 13 | 14 |

Welcome to chenxuan online disk!

15 |

this online disk run in cppweb

16 |

you can change password in config.json,default passwd is 123456

17 |

mkdir button is to create dir(name of input)

18 |

delete button is to delete dir(must be empty) or file(name of input)

19 |

update button is to reload now page

20 |

back button is to last page

21 |

move button is to move file or dir

22 |

edit button is to edit messsage online

23 |

link button is to create a web link

24 |

upload button is to send file to server(you have choose file before send)

25 |

default file storage in template dir

26 |

you can change config in config.json

27 |

For documentation and support please refer to 28 | Official website 29 | and give issue to me. 30 |
31 | If you think this project is useful,you can giive it a star 32 |
33 | author web 34 | chenxuanweb.

35 |

You can contact author by email 1607772321@qq.com

36 | 37 |

Thank you for using web server.

38 | 39 | 40 | -------------------------------------------------------------------------------- /src/example/online-disk/text.txt: -------------------------------------------------------------------------------- 1 | http://127.0.0.1:5200/edit -------------------------------------------------------------------------------- /src/example/ranking-list/api.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | API接口请求表单 8 | 32 | 33 | 34 |
35 |
36 |

请求地址: 37 |

38 |

参 数1: 39 |

40 |

参 数2: 41 |

42 |

参 数3: 43 |

44 |
45 |
46 |

参数1值 47 |

48 |

参数2值 49 |

50 |

参数3值 51 |

52 |

请求方式: 53 |

57 |

58 | 59 |

60 |
61 | 85 |
86 | 87 | 88 | -------------------------------------------------------------------------------- /src/example/ranking-list/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../../hpp/cppweb.h" 5 | using namespace std; 6 | using namespace cppweb; 7 | multimap tree; 8 | void addCLi(HttpServer& server,DealHttp& http,int) 9 | { 10 | http.req.analysisRequest(server.recText(http)); 11 | auto name=http.req.formValue("name"); 12 | auto scoStr=http.req.formValue("score"); 13 | if(scoStr.size()==0) 14 | { 15 | http.gram.json(DealHttp::STATUSOK,Json::createJson({ 16 | {"status","wrong"}, 17 | {"error","cannot find score"} 18 | })); 19 | return; 20 | } 21 | if(name.size()==0) 22 | { 23 | http.gram.json(DealHttp::STATUSOK,Json::createJson({ 24 | {"status","wrong"}, 25 | {"error","cannot find name"} 26 | })); 27 | return; 28 | } 29 | http.req.urlDecode(name); 30 | int score=0; 31 | if(0>=sscanf(scoStr.c_str(),"%d",&score)) 32 | { 33 | http.gram.json(DealHttp::STATUSOK,Json::createJson({ 34 | {"status","wrong"}, 35 | {"error","read score wrong"} 36 | })); 37 | return; 38 | } 39 | if(tree.size()<5) 40 | { 41 | printf("add success\n"); 42 | tree.insert(pair{score,name}); 43 | } 44 | else 45 | { 46 | if(score>tree.begin()->first) 47 | { 48 | tree.erase(tree.begin()); 49 | tree.insert(pair{score,name}); 50 | } 51 | } 52 | Json json={ 53 | {"name",name}, 54 | {"sco",score}, 55 | {"status","ok"} 56 | }; 57 | http.gram.json(DealHttp::STATUSOK,json()); 58 | } 59 | void getList(HttpServer&,DealHttp& http,int) 60 | { 61 | auto begin=tree.begin(); 62 | vector buf; 63 | Json json={{"status","ok"}}; 64 | while(begin!=tree.end()) 65 | { 66 | Json::Node node={ 67 | {"name",begin->second}, 68 | {"score",begin->first} 69 | }; 70 | printf("%d %s\n",begin->first,begin->second.c_str()); 71 | buf.push_back(node); 72 | begin++; 73 | } 74 | json["array"]=buf; 75 | http.gram.body=json(); 76 | http.gram.json(DealHttp::STATUSOK,json()); 77 | } 78 | int main() 79 | { 80 | HttpServer server(5200,true); 81 | if(server.lastError()!=NULL) 82 | { 83 | std::cout< 2 | #include "../../hpp/cppweb.h" 3 | using namespace cppweb; 4 | int main() 5 | { 6 | HttpServer server(5200,true);//input the port bound 7 | if(server.lastError()!=NULL) 8 | { 9 | std::cout< 2 | #include "../../hpp/cppweb.h" 3 | using namespace std; 4 | using namespace cppweb; 5 | void func(HttpServer&,DealHttp& http,int) 6 | { 7 | unordered_map hash; 8 | hash["name"]="chenxuan"; 9 | hash["lover"]="xiaozhu"; 10 | http.gram.body=FileGet::renderHtml("./test.html",hash); 11 | http.gram.typeFile=DealHttp::HTML; 12 | } 13 | int main() 14 | { 15 | HttpServer server(5200,true); 16 | server.get("/",func); 17 | server.run(); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /src/example/render-html/makefile: -------------------------------------------------------------------------------- 1 | all:main 2 | main:main.cpp ../../hpp/cppweb.h 3 | g++ main.cpp -o main -lpthread 4 | 5 | -------------------------------------------------------------------------------- /src/example/render-html/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |

{{ .name }}


10 |

{{ .lover }}


11 | 12 | -------------------------------------------------------------------------------- /src/example/request-struct/api.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | API接口请求表单 8 | 32 | 33 | 34 |
35 |
36 |

请求地址: 37 |

38 |

参 数1: 39 |

40 |

参 数2: 41 |

42 |

参 数3: 43 |

44 |
45 |
46 |

参数1值 47 |

48 |

参数2值 49 |

50 |

参数3值 51 |

52 |

请求方式: 53 |

57 |

58 | 59 |

60 |
61 | 85 |
86 | 87 | 88 | -------------------------------------------------------------------------------- /src/example/request-struct/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../hpp/cppweb.h" 3 | using namespace cppweb; 4 | void func(HttpServer&,DealHttp& http,int) 5 | { 6 | http.req.analysisRequest(http.info.recText); 7 | Json json={ 8 | {"ads",http.req.formValue("ads")}, 9 | {"fgf",http.req.formValue("fgf")} 10 | }; 11 | http.gram.json(DealHttp::STATUSOK,json()); 12 | } 13 | void getValue(HttpServer&,DealHttp& http,int) 14 | { 15 | http.req.analysisRequest(http.info.recText); 16 | auto value=http.req.queryValue("key"); 17 | std::cout<<"get:"< 2 | 3 | 4 | 32 | 33 | 34 |
35 |
36 |
恭喜!服务器运行成功

37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /src/example/route-use/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../hpp/cppweb.h" 3 | using namespace cppweb; 4 | using namespace std; 5 | void pfuncTwo(HttpServer&,DealHttp& http,int) 6 | { 7 | char temp[]="is a text file"; 8 | http.gram.statusCode=DealHttp::STATUSOK; 9 | http.gram.txt(DealHttp::STATUSOK,temp); 10 | } 11 | void pfunc(HttpServer&,DealHttp& http,int) 12 | { 13 | auto url=http.req.getWildUrl("/root/");//get url wild 14 | Json json={{"name",url},{"welcome","you"}}; 15 | http.gram.json(DealHttp::STATUSOK,json()); 16 | } 17 | void pfuncThree(HttpServer&,DealHttp& http,int) 18 | { 19 | http.req.analysisRequest(http.info.recText); 20 | unordered_map tree; 21 | http.req.routePairing("/try/:id/:name",tree); 22 | Json json={ 23 | {"id",tree["id"]}, 24 | {"name",tree["name"]} 25 | }; 26 | char* sen=(char*)http.info.sendBuffer->buffer; 27 | http.customizeAddTop(sen,http.info.sendBuffer->getMaxSize(),200,strlen(json())); 28 | int len=http.customizeAddBody(sen,http.info.sendBuffer->getMaxSize(),json(),strlen(json())); 29 | http.info.staticLen=len; 30 | } 31 | int main() 32 | { 33 | HttpServer server(5200,true);//input the port bound 34 | if(server.lastError()!=NULL) 35 | { 36 | std::cout<void{ 41 | http.gram.body="hahaha"; 42 | }); 43 | server.get("/txt",pfuncTwo); 44 | server.get("/try/*",pfuncThree); 45 | server.run("index.html"); 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /src/example/route-use/makefile: -------------------------------------------------------------------------------- 1 | all:main 2 | main:main.cpp ../../hpp/cppweb.h 3 | g++ main.cpp -o main -lpthread 4 | -------------------------------------------------------------------------------- /src/example/set-cookie/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../hpp/cppweb.h" 3 | using namespace cppweb; 4 | void cookie(HttpServer& server,DealHttp& http,int) 5 | { 6 | http.req.analysisRequest(http.info.recText); 7 | auto buf=http.req.getCookie("key"); 8 | printf("%s\n",(const char*)server.recText(http)); 9 | if(http.req.head.find("Cookie")==http.req.head.end()) 10 | printf("fing wrong\n"); 11 | else 12 | printf("cookie:%s\n\n",http.req.head["Cookie"].c_str()); 13 | std::unordered_map temp; 14 | http.req.routePairing("/cookie/:cookie/:time",temp,(char*)http.info.recText); 15 | if(buf.size()==0) 16 | { 17 | int live=5; 18 | http.gram.body="ready to setting cookie"; 19 | if(temp["time"].size()!=0) 20 | { 21 | sscanf(temp["time"].c_str(),"%d",&live); 22 | printf("live:%d\n",live); 23 | } 24 | else 25 | printf("ok\n"); 26 | if(live<=0) 27 | live=5; 28 | printf("live:%d\n",live); 29 | if(temp["cookie"].size()==0) 30 | http.gram.cookie["key"]=http.designCookie("cookie",live); 31 | else 32 | http.gram.cookie["key"]=http.designCookie(temp["cookie"].c_str(),live); 33 | return; 34 | } 35 | Json json={ 36 | {"key",buf}, 37 | {"status","ok"} 38 | }; 39 | http.gram.json(DealHttp::STATUSOK,json()); 40 | } 41 | int main() 42 | { 43 | HttpServer server(5200,true); 44 | server.get("/cookie/*",cookie); 45 | server.run("index.html"); 46 | return 0; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/example/set-cookie/makefile: -------------------------------------------------------------------------------- 1 | all:main 2 | main:main.cpp ../../hpp/cppweb.h 3 | g++ main.cpp -o main -lpthread 4 | 5 | -------------------------------------------------------------------------------- /src/example/ssl-https/cacert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDwTCCAqmgAwIBAgIUKXl2aOny80/tJ2DPEf+/9ExkArkwDQYJKoZIhvcNAQEL 3 | BQAwcDELMAkGA1UEBhMCemgxCzAJBgNVBAgMAmJqMQswCQYDVQQHDAJiajELMAkG 4 | A1UECgwCYmoxCzAJBgNVBAsMAmJqMQswCQYDVQQDDAJiajEgMB4GCSqGSIb3DQEJ 5 | ARYRMTYwNzc3MjMyMUBxcS5jb20wHhcNMjIwMzA5MTIxNTQzWhcNMjUwMzA4MTIx 6 | NTQzWjBwMQswCQYDVQQGEwJ6aDELMAkGA1UECAwCYmoxCzAJBgNVBAcMAmJqMQsw 7 | CQYDVQQKDAJiajELMAkGA1UECwwCYmoxCzAJBgNVBAMMAmJqMSAwHgYJKoZIhvcN 8 | AQkBFhExNjA3NzcyMzIxQHFxLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC 9 | AQoCggEBAMty7nZSQ0J3LEoLq/SUiTTRQaPjbhIxCyG0j8hI/OUGUUl1I5TKsBa0 10 | 8xY6LrWLIwfUk2LZh1x8GXiwwxTDYRdP76QG60b0/9buz+9uyJGEW0wsftVym5uG 11 | 3iWvzAPoHcb42cpMBHmQuVb/t+xXsPWXiEjMg7yZgEeWUVWEC684zhIbrDePFlaA 12 | PbasL1u5WkMSpA9iB6np7ObetuxIgR6iNuHWcrGnREDLv3eeUfWwnMZ89C3DzRXZ 13 | UnlerH3K4srLnCOB033yS63synYhc9RUOpPqN6uF9P5ADJ/am5Rnr5ZgpLY+VTIW 14 | I+3DmqXoC79QS58JZWqyJ1h686MgG7kCAwEAAaNTMFEwHQYDVR0OBBYEFG6R/78Z 15 | F2Y0Ad8+WuXsxjSNA75WMB8GA1UdIwQYMBaAFG6R/78ZF2Y0Ad8+WuXsxjSNA75W 16 | MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAA8rRUExflGwafOv 17 | SBHu10AI7HS8lUNm46dIm4Ds8wsBdiL6Yl6VIJp/t37zI5+kG4asQFr3UtCIKH7T 18 | vKbk9wldtqvHH5CTmm76KwjuY2g0ZBEZKqp27/f+QM6vW8uKEZuyH504VI/vnSE6 19 | GCgJx/Dyyvsamkggw1IZtF00PBLvBx/jNWlvObfKWNfUkP5K6X//t+qFvgSx/mRK 20 | b/T9qLjJwZcyRYYKwXWN/35AdKvRhBOp2ldIUoG58VYzyh1vaLA1BrWl/iErFVf/ 21 | KN40ZIyvQ5p66l1dBmprbT8zceyTmdqAkoOuYDR5iYeBANFSXXSQsS/G6205YqlG 22 | 1JRuEc0= 23 | -----END CERTIFICATE----- 24 | -------------------------------------------------------------------------------- /src/example/ssl-https/cert.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIC3zCCAccCAQAwcDELMAkGA1UEBhMCemgxCzAJBgNVBAgMAmJqMQswCQYDVQQH 3 | DAJiajELMAkGA1UECgwCYmoxCzAJBgNVBAsMAmJqMQswCQYDVQQDDAJiajEgMB4G 4 | CSqGSIb3DQEJARYRMTYwNzc3MjMyMUBxcS5jb20wggEiMA0GCSqGSIb3DQEBAQUA 5 | A4IBDwAwggEKAoIBAQDLcu52UkNCdyxKC6v0lIk00UGj424SMQshtI/ISPzlBlFJ 6 | dSOUyrAWtPMWOi61iyMH1JNi2YdcfBl4sMMUw2EXT++kButG9P/W7s/vbsiRhFtM 7 | LH7Vcpubht4lr8wD6B3G+NnKTAR5kLlW/7fsV7D1l4hIzIO8mYBHllFVhAuvOM4S 8 | G6w3jxZWgD22rC9buVpDEqQPYgep6ezm3rbsSIEeojbh1nKxp0RAy793nlH1sJzG 9 | fPQtw80V2VJ5Xqx9yuLKy5wjgdN98kut7Mp2IXPUVDqT6jerhfT+QAyf2puUZ6+W 10 | YKS2PlUyFiPtw5ql6Au/UEufCWVqsidYevOjIBu5AgMBAAGgKjARBgkqhkiG9w0B 11 | CQIxBAwCemgwFQYJKoZIhvcNAQkHMQgMBjEyMzQ1NjANBgkqhkiG9w0BAQsFAAOC 12 | AQEARqMLuZ+gVzVA9VzYtGBnr7y7WBRuso6hwpIos9xap66UsfzjkBysKpzF8Msh 13 | nBREJXDvDxcj6pRDHHYhqO288lDsvSKpf7bkgol738C9S8yZYyzz5lnHB7fwJ8l+ 14 | EcvtraffZYX9BbtzDPuW0ZlizPKCEV3ReMrADFIMIDQ6vHdEQgFPY4CUEDwmD6kq 15 | tPYJIQPe5bDIeKyHRGptmOnar+bZzD2UvQeNspbiFidIzGxuoU837sLd9lkVIGIO 16 | uqvH/NgvpA72pqyw8k8w+dAOkr8I+/mzaupaW8uI5n+Qwxq4ZiY0z7Qa+lcJ5be6 17 | zWBqw7IhWloDiRTSx6JvGTtuvw== 18 | -----END CERTIFICATE REQUEST----- 19 | -------------------------------------------------------------------------------- /src/example/ssl-https/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Welcome to chenxuan server! 5 | 12 | 13 | 14 |

Welcome chenxuan server!

15 |

If you see this page, the web server is successfully installed and 16 | working.

17 | 18 |

For documentation and support please refer to 19 | gitee.
20 | author web 21 | chenxuanweb.

22 | 23 |

Thank you for using my server.

24 | 25 | 26 | -------------------------------------------------------------------------------- /src/example/ssl-https/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define CPPWEB_OPENSSL 3 | #include "../../hpp/cppweb.h" 4 | using namespace std; 5 | using namespace cppweb; 6 | int main() 7 | { 8 | HttpServer server(5201,true,HttpServer::THREAD,5); 9 | server.loadKeyCert("./cacert.pem","./privkey.pem","123456"); 10 | server.run("./index.html"); 11 | printf("error:%s\n",server.lastError()); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /src/example/ssl-https/makefile: -------------------------------------------------------------------------------- 1 | all:main 2 | main:main.cpp ../../hpp/cppweb.h 3 | g++ main.cpp -o main -lpthread -lssl -lcrypto 4 | 5 | -------------------------------------------------------------------------------- /src/example/ssl-https/privkey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: DES-EDE3-CBC,DF432D4EED4C9BAD 4 | 5 | wBogMY11N1pvhXXbbVY1xJefJxyvDtOWwNWSIZDZZRmQwKa/xkUaNbOFBUQUsJ6N 6 | jwk/RpI64ExoohJyu8ys0YnrHV9TsBE79fjjJ8/xqX+jaliYkKMk5mFvna1qGXiC 7 | fSRw478JGOCfanhYXBwgt9znRSN3QIucfoSJ5cgu1Xji5kzXEL208MKGcRMlarfi 8 | O6iChzQSYHmuNoNeTDbEnUaU6g4iNbAAyACr56EMWIfvI/2HranuLkub8yp4d95f 9 | vxUBlKUu5k7btOS5dBDDmwneQvAUmVPF3We4zfYqg9U8/KkO9K9m1xILZT85klxH 10 | NPOaTZzSR2OwWvaiXgw1n/+PK0cIBo/aKWORkcOFDiIDaNLcr+Qci1xXsQEMXmrt 11 | ZMDeyKm4Ia/RMUbrTfA4nJYP4xwa8mguQM2TuQg7zaYysQz1mRsG+Gn8nQhwShnk 12 | QvXkm2CbdF4Xue4FS02dzVUh1Zat0OURkDrcJu1OeTUEX/3b5NCm9dJWVf5dk7tl 13 | CskbE/EbENQELF/5V5pLsnxXdPGuP/mAUKJNvadJBAX18UasgNrMxCEoGP1ibiBG 14 | fCrR8cYi54mE20wT9Z0J2UgIrASjRPLRsDqzwxCfFk4yPuwXBTFnx/y8uD1F7gho 15 | GU9CW3s+6R0eLw0rR4K18bWiEoQlu2S7xkfZ1Aecwi1dPxChvCiuawA2SeByGWVk 16 | JWQzvJ/EKQIuwuJ/KCB5ziUlQmN725uh4VA7Uq5QBxFrpY4nNU7z0uqoF6JpiSV0 17 | vwczgnQXSEyylSrqnQvYfaMO1DFgGMMNWUgK9lAvRpjKqS7ZmSNHKlQkuxq9N9Lq 18 | ZWIjUrYXYkFHae9/caZLI6pgZcJhVtYG+e3sMe2l2hDZvBiAZ+04stwlxaLxgT/H 19 | 4LXuR29l/i32r1P9pJkIXIVAWwS2YtDehqWueOEkzosmrveRUlxTZH+E+K1aO9zQ 20 | ik1kcv+WXkydzFoy2mlaTGAPfvYGLBFrY5CMachTbb36++W266KjYfY3GknD1X77 21 | zFWSd0rTxdFBM+XlSP/VwGBPEBsbQpQdHWUrxVrim8Shbx8cJm9UmSuQUpeSxufD 22 | 3ZSoT2xTv/NFMsDqekPUSSWg5uc8RxbM9XFjndFhxxDcNMdFF1skD673TxJ+eFgq 23 | fPBAeQIdjZmLqtk1zNsn/rbSkK3Vw0svRQsrqS8HDA7t8zYESM/TRFTZvpRUHo6R 24 | KWCrqnz7TjhnGr35qJ/SsJ9TzPF+doiedjNCpZkBXop0gIycNZvxacmj+ZXBPvhZ 25 | mHW6UcqX1F4/JqYNYyNPowVk20457PrOk+iAFL1hGRNOjoW/0h+6Qv0ayWcfY6ed 26 | BOAfE4SJ0NV1M+Bxg2kyDHTLwpHthlDGntUECGSh+wUXW5dNfYSSBuomU/vnKxy4 27 | 3qoYZvEM6HVUYCsPhOzJAcnoBxaZL1Kay0sZzml7kBmaVIJNlgVuh34V1yacKkc+ 28 | 9uqnkFbI/z2BJMBcMRprebOICzxDLwebwhKjbOrHwQ7G50HNhOKNVIR4AQkFyr9u 29 | qyoUoC1t/I0ZpwJm06hg3Bsd3aOWiqkKQdJWntSrQ1HIBFRPJGy8LA== 30 | -----END RSA PRIVATE KEY----- 31 | -------------------------------------------------------------------------------- /src/example/ssl-https/step.md: -------------------------------------------------------------------------------- 1 | ## https服务器安装方法 2 | 3 | ### 前提 4 | 5 | 1. 安装好openssl 6 | 7 | 2. 拥有https证书(openssl自己签发也可以) 8 | 9 | ### 自签发证书 10 | 11 | - 使用shell 12 | 13 | - 如果有证书可以忽略 14 | 15 | ```shell 16 | openssl genrsa -des3 -out privkey.pem 2048 17 | openssl req -new -key privkey.pem -out cert.csr 18 | openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095 19 | ``` 20 | 21 | ### 使用方法 22 | 23 | 1. 在包含头文件之前 24 | 25 | > #define CPPWEB_OPENSSL 26 | 27 | 2. 在初始化HttpServer之后加载证书 28 | 29 | > 具体见main.cpp 30 | -------------------------------------------------------------------------------- /src/example/static-file/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 服务器生成 10 | 11 | 131 | 132 | 133 | 134 | 135 |
136 | 137 |
138 |

配置填写

139 |

请填写以下内容,然后就可以自动生成服务器!

140 |
141 | 142 |
143 |
144 | 145 |
146 |
147 | 148 |
149 |
150 | 151 |
152 |
153 | 154 |
155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 |
165 | 166 |
167 |
168 | 169 | -------------------------------------------------------------------------------- /src/example/static-file/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../hpp/cppweb.h" 3 | using namespace cppweb; 4 | int main() 5 | { 6 | HttpServer server(5200,true); 7 | server.loadStatic("/root/*","./temp/"); 8 | server.loadStatic("/file","index.html"); 9 | if(server.lastError()!=NULL) 10 | { 11 | std::cout< 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 服务器生成 10 | 11 | 131 | 132 | 133 | 134 | 135 |
136 | 137 |
138 |

配置填写

139 |

请填写以下内容,然后就可以自动生成服务器!

140 |
141 | 142 |
143 |
144 | 145 |
146 |
147 | 148 |
149 |
150 | 151 |
152 |
153 | 154 |
155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 |
165 | 166 |
167 |
168 | 169 | -------------------------------------------------------------------------------- /src/example/thread-model/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 32 | 33 | 34 |
35 |
36 |
恭喜!服务器运行成功

37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /src/example/thread-model/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../hpp/cppweb.h" 3 | using namespace std; 4 | using namespace cppweb; 5 | void func(ServerPool& server,int soc) 6 | { 7 | char rec[10000]={0}; 8 | char* sen=(char*)malloc(sizeof(char)*1000000); 9 | if(sen==NULL) 10 | { 11 | printf("malloc worng\n"); 12 | return; 13 | } 14 | server.receiveSocket(soc,rec,10000); 15 | DealHttp http; 16 | printf("get %s\n",http.analysisHttpAsk(rec)); 17 | int len=0; 18 | int flag=http.autoAnalysisGet(rec,sen,1000000,"./index.html",&len); 19 | if(flag==2) 20 | printf("open wrong\n"); 21 | if(len<=0) 22 | { 23 | printf(" len wrong\n%s\n",rec); 24 | free(sen); 25 | return ; 26 | } 27 | if(server.sendSocket(soc,sen,len)<=0) 28 | printf("%s\n",server.lastError()); 29 | else 30 | printf("send success\n"); 31 | server.disconnectSocket(soc); 32 | free(sen); 33 | printf("end thread\n"); 34 | } 35 | int main() 36 | { 37 | ServerPool server(5200,10); 38 | if(false==server.bondhost()) 39 | { 40 | printf("bound wrong %s\n",server.lastError()); 41 | return 0; 42 | } 43 | server.setlisten(); 44 | server.threadModel(func); 45 | return 0; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/example/thread-model/makefile: -------------------------------------------------------------------------------- 1 | all:main 2 | main:main.cpp 3 | g++ -g main.cpp -o main -lpthread 4 | 5 | -------------------------------------------------------------------------------- /src/example/upload-file/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | hahahaha 5 | 6 | 7 |
8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /src/example/upload-file/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../../hpp/cppweb.h" 4 | using namespace std; 5 | using namespace cppweb; 6 | void upload(HttpServer& server,DealHttp& http,int soc) 7 | { 8 | char name[100]={0}; 9 | DealHttp::Request req; 10 | if(false==http.analysisRequest(req,server.recText(http))) 11 | { 12 | Json json={{"status","analysisHttpAsk wrong"}}; 13 | http.gram.json(DealHttp::STATUSOK,json()); 14 | return; 15 | } 16 | if(req.head.find("Content-Length")==req.head.end()) 17 | { 18 | http.gram.body="message wrong"; 19 | return; 20 | } 21 | char path[128]={0}; 22 | http.getWildUrl(server.recText(http),server.getNowRoute()->route,path,sizeof(char)*128); 23 | req.askPath="."; 24 | req.askPath+=path; 25 | int flen=0; 26 | sscanf(req.head["Content-Length"].c_str(),"%d",&flen); 27 | void *temp=malloc(sizeof(char)*(flen+1000)); 28 | if(temp==NULL) 29 | { 30 | http.gram.statusCode=DealHttp::STATUSNOFOUND; 31 | return; 32 | } 33 | memset(temp,0,sizeof(char)*(flen+1000)); 34 | flen=http.getRecFile(server.recText(http),server.getRecLen(http),name,100,(char*)temp,sizeof(char)*(flen+1000)); 35 | req.askPath+=name; 36 | cout<<"file:"< 2 | 3 | 4 | 32 | 33 | 34 |
35 |
36 |
恭喜!服务器运行成功

37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /src/example/use-cppweb/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../hpp/cppweb.h" 3 | using namespace cppweb; 4 | int main() 5 | { 6 | HttpServer server(5200,true); 7 | server.run("index.html"); 8 | return 0; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/example/use-cppweb/makefile: -------------------------------------------------------------------------------- 1 | all:main 2 | main:main.cpp ../../hpp/cppweb.h 3 | g++ main.cpp -o main -lpthread 4 | 5 | -------------------------------------------------------------------------------- /src/hpp/argc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | namespace cppweb{ 6 | class ArgcDeal{ 7 | public: 8 | struct AppMsg{ 9 | std::string name; 10 | std::string version; 11 | std::string usage; 12 | int (*pfunc)(ArgcDeal&); 13 | }; 14 | private: 15 | char** argv; 16 | int argc; 17 | std::unordered_map argAll; 18 | std::unordered_map message; 19 | public: 20 | AppMsg app; 21 | public: 22 | ArgcDeal(int argc,char** argv):argv(argv),argc(argc){ 23 | for(int i=1;i 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | /*********************************************** 9 | * Author: chenxuan-1607772321@qq.com 10 | * change time:2022-04-29 20:12:36 11 | * description: md5 base openssl 12 | * example: auto result=Md5::encode(text,textLen) 13 | ***********************************************/ 14 | class Md5 { 15 | private: 16 | Md5() = delete; 17 | Md5(const Md5 &) = delete; 18 | 19 | public: 20 | static std::string encode(const char *text, int textLen, char *buff = NULL) { 21 | unsigned char temp[16] = {0}; 22 | char buffer[33] = {0}, ch[3] = {0}; 23 | MD5((const unsigned char *)text, textLen, temp); 24 | for (unsigned i = 0; i < 16; i++) { 25 | sprintf(ch, "%02x", temp[i]); 26 | strcat(buffer, ch); 27 | } 28 | std::string result = buffer; 29 | if (buff != NULL) 30 | memcpy(buff, buffer, 32); 31 | return result; 32 | } 33 | }; 34 | /*********************************************** 35 | * Author: chenxuan-1607772321@qq.com 36 | * change time:2022-04-29 20:13:18 37 | * description:base64 base in openssl 38 | * example: {auto result=Base64::encode(text,textlen); 39 | * result=Base64::decode(text.c_str,text.size);} 40 | ***********************************************/ 41 | class Base64 { 42 | private: 43 | Base64() = delete; 44 | Base64(const Base64 &) = delete; 45 | 46 | public: 47 | static const char *error; 48 | static std::string encode(const char *text, int len) { 49 | if (text == NULL || len <= 0) { 50 | error = "wrong input"; 51 | return ""; 52 | } 53 | unsigned char *buffer = 54 | (unsigned char *)malloc((len + 1) * 2 * sizeof(unsigned char)); 55 | if (buffer == NULL) { 56 | error = "memory malloc wrong"; 57 | return ""; 58 | } 59 | memset(buffer, 0, (len + 1) * 2 * sizeof(unsigned char)); 60 | EVP_EncodeBlock(buffer, (const unsigned char *)text, len); 61 | std::string result = (char *)buffer; 62 | free(buffer); 63 | return result; 64 | } 65 | static std::string decode(const char *text, int len) { 66 | if (text == NULL) { 67 | error = "null input"; 68 | return ""; 69 | } 70 | char *buffer = (char *)malloc(len * sizeof(char)); 71 | if (buffer == NULL) { 72 | error = "memory malloc wrong"; 73 | return ""; 74 | } 75 | memset(buffer, 0, len * sizeof(char)); 76 | int nTextLen = EVP_DecodeBlock((unsigned char *)buffer, 77 | (const unsigned char *)text, len); 78 | if (nTextLen == -1) { 79 | free(buffer); 80 | return ""; 81 | } 82 | std::string result(buffer, nTextLen); 83 | free(buffer); 84 | return result; 85 | } 86 | }; 87 | const char *Base64::error = NULL; 88 | -------------------------------------------------------------------------------- /src/hpp/proxy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "./cppweb.h" 3 | using namespace cppweb; 4 | /*********************************************** 5 | * Author: chenxuan-1607772321@qq.com 6 | * change time:2022-03-17 19:20:18 7 | * description:class for Reverse proxy 8 | * example:{ LoadBalance load(RANDOM) 9 | * load.addServer("127.0.0.1:5200") 10 | * char* getIp=load.getServer(); 11 | * } 12 | ***********************************************/ 13 | class LoadBalance{ 14 | public: 15 | enum Model{ 16 | POLLING,//one by one 17 | POLLRAN,//polling by random 18 | RANDOM,//random find 19 | HASH,//use hash 20 | TEMPNO//a temp model do not use it 21 | }; 22 | private: 23 | Model model; 24 | std::vector ipAddr; 25 | std::vector ipWeight; 26 | unsigned int pollingNum; 27 | unsigned int widghtAll; 28 | public: 29 | LoadBalance(Model choice) 30 | { 31 | this->model=choice; 32 | pollingNum=0; 33 | widghtAll=0; 34 | char* ptemp=(char*)malloc(0); 35 | srand((unsigned int)((long long int)ptemp)); 36 | free(ptemp); 37 | } 38 | bool addModel(Model choice) 39 | { 40 | if(model!=TEMPNO) 41 | return false; 42 | model=choice; 43 | return true; 44 | } 45 | void addServer(const char* ip,int weight) 46 | { 47 | switch(model) 48 | { 49 | case HASH: 50 | case POLLING: 51 | case POLLRAN: 52 | for(int i=0;i=ipAddr.size()) 74 | pollingNum=0; 75 | temp=ipAddr[pollingNum++].c_str(); 76 | break; 77 | case POLLRAN: 78 | temp=ipAddr[rand()%ipAddr.size()].c_str(); 79 | break; 80 | case RANDOM: 81 | num=rand()%widghtAll; 82 | for(unsigned int i=0;inum) 84 | { 85 | temp=ipAddr[i].c_str(); 86 | break; 87 | } 88 | else 89 | num-=ipWeight[i]; 90 | break; 91 | case HASH: 92 | case TEMPNO: 93 | break; 94 | } 95 | return temp; 96 | } 97 | bool deleteServer(const char* ip) 98 | { 99 | bool flag=false; 100 | std::vector::iterator temp=ipAddr.begin(); 101 | for(;tempc_str())==0) 103 | { 104 | if(model==RANDOM) 105 | { 106 | widghtAll-=ipWeight[temp-ipAddr.begin()]; 107 | std::vector::iterator ptemp=ipWeight.begin(); 108 | ptemp+=temp-ipAddr.begin(); 109 | ipWeight.erase(ptemp); 110 | } 111 | ipAddr.erase(temp); 112 | temp--; 113 | flag=true; 114 | } 115 | return flag; 116 | } 117 | const char* getHashServer(const char* clientIp) 118 | { 119 | unsigned int one=0,two=0,three=0,four=0; 120 | if(0>=sscanf(clientIp,"%d.%d.%d.%d",&one,&two,&three,&four)) 121 | return NULL; 122 | return ipAddr[(one+two+three+four)%ipAddr.size()].c_str(); 123 | } 124 | inline Model getNowModel() 125 | { 126 | return model; 127 | } 128 | }loadBanlance(LoadBalance::TEMPNO); 129 | /*********************************************** 130 | * Author: chenxuan-1607772321@qq.com 131 | * change time:2022-04-02 19:17:21 132 | * description:http and https ForwardProxy,donnot change or use this class 133 | ***********************************************/ 134 | class ForwardProxy{ 135 | private: 136 | static void *httpsTunnel(void* arg) 137 | { 138 | std::pair &_arg = *(std::pair *)arg; 139 | int soc = _arg.first; 140 | char *buffer = (char *)malloc(sizeof(char) * 1024 * 512); 141 | if (buffer == NULL) 142 | { 143 | printf("malloc error\n"); 144 | return NULL; 145 | } 146 | int len = 0; 147 | while (true) 148 | { 149 | memset(buffer, 0, 1024 * 512); 150 | len = recv(_arg.second, buffer, sizeof(char) * 1024 * 512, 0); 151 | if (len <= 0) 152 | break; 153 | if (send(soc, buffer, len, 0) <= 0) 154 | break; 155 | } 156 | free(buffer); 157 | return NULL; 158 | } 159 | public: 160 | static void httpProxy(HttpServer &server, DealHttp &http, int) 161 | { 162 | DealHttp::Request req; 163 | http.analysisRequest(req, server.recText(http)); 164 | char top[128] = {0}, end[128] = {0}; 165 | DealHttp::dealUrl(req.askPath.c_str(), top, end, 128, 128); 166 | req.askPath = end; 167 | http.createAskRequest(req, server.getSenBuffer(http), server.getMaxSenLen(http)); 168 | auto serverIP=ClientTcpIp::getDnsIp(top); 169 | char *sen = (char *)server.getSenBuffer(http); 170 | ClientTcpIp client(serverIP, 80); 171 | if (client.tryConnect() == false) 172 | { 173 | http.gram.statusCode = DealHttp::STATUSNOFOUND; 174 | return; 175 | } 176 | if (client.sendHost(sen, strlen(sen)) <= 0) 177 | { 178 | http.gram.statusCode = DealHttp::STATUSNOFOUND; 179 | return; 180 | } 181 | int len = 0; 182 | std::string rec; 183 | if ((len = client.receiveHost(rec)) <= 0) 184 | { 185 | http.gram.statusCode = DealHttp::STATUSNOFOUND; 186 | return; 187 | } 188 | if (server.getMaxSenLen(http) < rec.size()) 189 | { 190 | server.enlagerSenBuffer(); 191 | } 192 | memcpy(server.getSenBuffer(http), rec.c_str(), rec.size()); 193 | http.info.staticLen=rec.size(); 194 | } 195 | static void httpsProxy(HttpServer &server, DealHttp &http, int soc) 196 | { 197 | DealHttp::Request req; 198 | int port = 0; 199 | http.analysisRequest(req, http.info.recText); 200 | char buffer[2048] = {0}; 201 | sscanf(req.askPath.c_str(), "%[^:]:%d", buffer, &port); 202 | auto serverIP=ClientTcpIp::getDnsIp(buffer); 203 | ClientTcpIp client(serverIP, port); 204 | if (false == client.tryConnect()) 205 | { 206 | http.gram.statusCode = DealHttp::STATUSNOFOUND; 207 | printf("connect error\n"); 208 | return; 209 | } 210 | auto len = sprintf((char *)buffer, "HTTP/1.1 200 Connection Established\r\n" 211 | "Connection:close\r\n\r\n"); 212 | server.httpSend(soc, buffer, len); 213 | std::pair now = {soc, client.getSocket()}; 214 | ThreadPool::createDetachPthread(&now,httpsTunnel); 215 | char *temp = (char *)server.getSenBuffer(http); 216 | int maxLen = server.getMaxSenLen(http); 217 | while (true) 218 | { 219 | len = server.httpRecv(soc, temp, maxLen); 220 | if (len <= 0) 221 | break; 222 | len = client.sendHost(temp, len); 223 | if (len <= 0) 224 | break; 225 | } 226 | http.info.staticLen=0; 227 | } 228 | }; 229 | -------------------------------------------------------------------------------- /src/hpp/route.h: -------------------------------------------------------------------------------- 1 | #ifndef _ROUTE_H_ 2 | #define _ROUTE_H_ 3 | #include "cppweb.h" 4 | #include "./config.h" 5 | using namespace cppweb; 6 | extern Config config; 7 | /******************************** 8 | author:chenxuan 9 | date:2021/11/7 10 | funtion:funtion for 2.0 server add handle 11 | *********************************/ 12 | void addHandle(HttpServer& ) 13 | { 14 | } 15 | #endif 16 | -------------------------------------------------------------------------------- /src/hpp/serverpool.cpp: -------------------------------------------------------------------------------- 1 | #include "../hpp/cppweb.h" 2 | namespace cppweb{ 3 | /******************************* 4 | * author:chenxuan 5 | * class:the same as servertcpip but it use threadpool 6 | * example:see ServerTcpIp 7 | ******************************/ 8 | class ServerPool:public ServerTcpIp{ 9 | private: 10 | struct Argv{ 11 | ServerPool* pserver; 12 | void (*func)(ServerPool&,int); 13 | int soc; 14 | Argv() 15 | { 16 | pserver=NULL; 17 | soc=-1; 18 | func=NULL; 19 | } 20 | }; 21 | private: 22 | ThreadPool* pool; 23 | pthread_mutex_t mutex; 24 | unsigned int threadNum; 25 | bool isEpoll; 26 | private: 27 | #ifndef _WIN32 28 | static void sigCliDeal(int ) 29 | { 30 | while(waitpid(-1, NULL, WNOHANG)>0); 31 | } 32 | #endif 33 | static void* worker(void* argc) 34 | { 35 | Argv argv=*(Argv*)argc; 36 | delete (Argv*)argc; 37 | if(argv.func!=NULL) 38 | argv.func(*argv.pserver,argv.soc); 39 | return NULL; 40 | } 41 | public: 42 | ServerPool(unsigned short port,unsigned int threadNum=0):ServerTcpIp(port) 43 | { 44 | this->threadNum=threadNum; 45 | if(threadNum>0) 46 | { 47 | pool=new ThreadPool(threadNum); 48 | if(pool==NULL) 49 | { 50 | this->error="malloc wrong"; 51 | return; 52 | } 53 | } 54 | pthread_mutex_init(&mutex,NULL); 55 | isEpoll=false; 56 | } 57 | ~ServerPool() 58 | { 59 | delete pool; 60 | pthread_mutex_destroy(&mutex); 61 | } 62 | inline void mutexLock() 63 | { 64 | pthread_mutex_lock(&mutex); 65 | } 66 | inline void mutexUnlock() 67 | { 68 | pthread_mutex_unlock(&mutex); 69 | } 70 | bool mutexTryLock() 71 | { 72 | if(0==pthread_mutex_trylock(&mutex)) 73 | return true; 74 | else 75 | return false; 76 | } 77 | void threadModel(void (*pfunc)(ServerPool&,int)) 78 | { 79 | if(this->threadNum==0) 80 | { 81 | this->error="thread wrong init"; 82 | return; 83 | } 84 | while(1) 85 | { 86 | sockaddr_in newaddr={0,0,{0},{0}}; 87 | int newClient=acceptSocket(newaddr); 88 | if(newClient==-1) 89 | continue; 90 | Argv* temp=new Argv; 91 | if(temp==NULL) 92 | { 93 | error="malloc wrong"; 94 | return; 95 | } 96 | temp->pserver=this; 97 | temp->func=pfunc; 98 | temp->soc=newClient; 99 | ThreadPool::Task task={worker,temp}; 100 | pool->addTask(task); 101 | } 102 | } 103 | #ifndef _WIN32 104 | void forkModel(void* pneed,void (*pfunc)(ServerPool&,int,void*)) 105 | { 106 | signal(SIGCHLD,sigCliDeal); 107 | while(1) 108 | { 109 | sockaddr_in newaddr={0,0,{0},{0}}; 110 | int newClient=accept(sock,(sockaddr*)&newaddr,(socklen_t*)&sizeAddr); 111 | if(newClient==-1) 112 | continue; 113 | if(fork()==0) 114 | { 115 | close(sock); 116 | pfunc(*this,newClient,pneed); 117 | } 118 | close(newClient); 119 | } 120 | } 121 | void forkEpoll(unsigned int senBufChar,unsigned int recBufChar,void (*pfunc)(ServerPool::Thing,int,int,void*,void*,ServerPool&)) 122 | { 123 | signal(SIGCHLD,sigCliDeal); 124 | char* pneed=(char*)malloc(sizeof(char)*senBufChar),*pget=(char*)malloc(sizeof(char)*recBufChar); 125 | if(pneed==NULL||pget==NULL) 126 | { 127 | this->error="malloc worng"; 128 | return; 129 | } 130 | memset(pneed,0,sizeof(char)*senBufChar); 131 | memset(pget,0,sizeof(char)*recBufChar); 132 | while(1) 133 | { 134 | int eventNum=epoll_wait(epfd,pevent,512,-1),thing=0; 135 | for(int i=0;i0) 152 | thing=2; 153 | else 154 | { 155 | *(char*)pget=0; 156 | thing=0; 157 | epoll_ctl(epfd,temp.data.fd,EPOLL_CTL_DEL,NULL); 158 | close(temp.data.fd); 159 | } 160 | if(pfunc!=NULL&&thing==2) 161 | { 162 | if(fork()==0) 163 | { 164 | close(sock); 165 | pfunc(CPPSAY,temp.data.fd,getNum,pget,pneed,*this); 166 | close(temp.data.fd); 167 | free(pneed); 168 | free(pget); 169 | exit(0); 170 | } 171 | else 172 | { 173 | epoll_ctl(epfd,temp.data.fd,EPOLL_CTL_DEL,NULL); 174 | close(temp.data.fd); 175 | } 176 | } 177 | } 178 | } 179 | } 180 | } 181 | void epollThread(void (*pfunc)(ServerPool&,int)) 182 | { 183 | if(this->threadNum==0) 184 | { 185 | this->error="thread wrong init"; 186 | return; 187 | } 188 | isEpoll=true; 189 | int eventNum=epoll_wait(epfd,pevent,512,-1); 190 | for(int i=0;ifunc=pfunc; 207 | argv->soc=temp.data.fd; 208 | argv->pserver=this; 209 | ThreadPool::Task task={worker,argv}; 210 | pool->addTask(task); 211 | } 212 | } 213 | } 214 | return; 215 | } 216 | #endif 217 | inline void threadDeleteSoc(int clisoc) 218 | { 219 | closeSocket(clisoc); 220 | #ifndef _WIN32 221 | if(isEpoll) 222 | epoll_ctl(epfd,clisoc,EPOLL_CTL_DEL,NULL); 223 | #endif 224 | } 225 | }; 226 | } 227 | 228 | -------------------------------------------------------------------------------- /src/hpp/sql.h: -------------------------------------------------------------------------------- 1 | #ifndef _SQL_H_ 2 | #define _SQL_H_ 3 | #include 4 | class MySql{ 5 | private: 6 | MYSQL* mysql; 7 | MYSQL one; 8 | MYSQL_RES* results; 9 | MySql(MySql&); 10 | MySql& operator==(MySql&); 11 | public: 12 | MySql(const char* ipOrHostName,const char* user,const char* passwd,const char* dataBaseName); 13 | ~MySql(); 14 | int MySqlSelectQuery(const char* sql); 15 | bool MySqlOtherQuery(const char* sql); 16 | char** MySqlGetResultRow(); 17 | }; 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /src/test/arg_test.cpp: -------------------------------------------------------------------------------- 1 | #include "../hpp/argc.h" 2 | using namespace cppweb; 3 | int _main(ArgcDeal& app){ 4 | auto value=app.getVari("config"); 5 | printf("get %s\n",value.c_str()); 6 | return 0; 7 | } 8 | int main(int argc,char** argv){ 9 | ArgcDeal msg(argc,argv); 10 | msg.app.name="argc test"; 11 | msg.app.usage="a no use test help"; 12 | msg.app.version="v1.0"; 13 | msg.app.pfunc=_main; 14 | msg.setVari("config","the config file",true); 15 | msg.setOption("p","the test option",true); 16 | return msg.run(); 17 | } 18 | -------------------------------------------------------------------------------- /src/test/base64_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../hpp/encrypt.h" 3 | #include 4 | #include 5 | using namespace std; 6 | int main() 7 | { 8 | string temp; 9 | cin>>temp; 10 | auto re2=Base64::encode(temp.c_str(),temp.size()); 11 | cout<<"result2:"<client.sendHost(buffer.c_str(),buffer.size())) 22 | { 23 | perror("send"); 24 | return 0; 25 | } 26 | string result; 27 | if(0>client.receiveHost(result)) 28 | { 29 | perror("recv"); 30 | return 0; 31 | } 32 | auto flag=req.analysisRequest(result.c_str()); 33 | if(!flag) 34 | { 35 | cout<<"wrong:"<0, "data_num is "<0, "data_num is "< 5 | #include 6 | #include 7 | 8 | void* ConfigServer(void*){ 9 | cppweb::HttpServer server(5200); 10 | //define stop function 11 | server.get("/stop",[](cppweb::HttpServer& server,cppweb::DealHttp& http,int){server.stopServer();}); 12 | 13 | //txt ping-pong test 14 | server.get("/ping",[](cppweb::HttpServer&,cppweb::DealHttp& http,int){http.gram.txt(cppweb::DealHttp::STATUSOK, "pong");}); 15 | 16 | //get query var 17 | server.get("/query",[](cppweb::HttpServer&,cppweb::DealHttp& http,int){ 18 | auto val=http.req.queryValue("temp"); 19 | http.gram.txt(cppweb::DealHttp::STATUSOK,val); 20 | }); 21 | 22 | //post from val 23 | server.post("/postvar",[](cppweb::HttpServer&,cppweb::DealHttp& http,int){ 24 | auto val=http.req.formValue("temp"); 25 | http.gram.txt(cppweb::DealHttp::STATUSOK,val); 26 | }); 27 | 28 | //get wild route pair 29 | server.get("/wild/*",[](cppweb::HttpServer&,cppweb::DealHttp& http,int){ 30 | http.gram.txt(cppweb::DealHttp::STATUSOK, "wild"); 31 | }); 32 | 33 | //trye cookie read 34 | server.get("/read_cookie",[](cppweb::HttpServer&,cppweb::DealHttp& http,int){ 35 | auto val=http.req.getCookie("cookie_try"); 36 | http.gram.txt(cppweb::DealHttp::STATUSOK,val); 37 | }); 38 | 39 | server.run(); 40 | return nullptr; 41 | } 42 | 43 | INIT(CreateServer){ 44 | cppweb::ThreadPool::createDetachPthread(nullptr,ConfigServer); 45 | return 0; 46 | } 47 | END(OnlineTest_Clean){ 48 | system("rm temp"); 49 | } 50 | 51 | std::string getCurlResult(const std::string& cmd){ 52 | std::string cmd_fin=cmd+" 2>/dev/null 1>temp"; 53 | auto temp_no_use=system(cmd_fin.c_str()); 54 | std::fstream file("temp"); 55 | std::stringstream buffer; 56 | buffer << file.rdbuf(); 57 | return buffer.str(); 58 | } 59 | 60 | TEST(ResufulApi, PingPong){ 61 | MUST_EQUAL(getCurlResult("curl http://127.0.0.1:5200/ping"), "pong"); 62 | } 63 | 64 | TEST(ResufulApi, QueryVar){ 65 | MUST_EQUAL(getCurlResult("curl http://127.0.0.1:5200/query?temp=hello"), "hello"); 66 | } 67 | 68 | TEST(ResufulApi, PostFormVar){ 69 | MUST_EQUAL(getCurlResult("curl http://127.0.0.1:5200/postvar -d 'temp=post' -X POST"), "post"); 70 | } 71 | 72 | TEST(ResufulApi, RouteWild){ 73 | MUST_EQUAL(getCurlResult("curl http://127.0.0.1:5200/wild/one"), "wild"); 74 | MUST_EQUAL(getCurlResult("curl http://127.0.0.1:5200/wild/two"), "wild"); 75 | } 76 | 77 | TEST(ResufulApi, WrongRoute){ 78 | MUST_EQUAL(getCurlResult("curl http://127.0.0.1:5200/empty/one"),"404 no found"); 79 | } 80 | 81 | TEST(ResufulApi, CookieRead){ 82 | MUST_EQUAL(getCurlResult("curl http://127.0.0.1:5200/read_cookie --cookie 'cookie_try=val'"), "val"); 83 | } 84 | -------------------------------------------------------------------------------- /src/test/regex_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../hpp/cppweb.h" 3 | using namespace std; 4 | using namespace cppweb; 5 | void func(HttpServer&,DealHttp& http,int) 6 | { 7 | unordered_map hash; 8 | hash["name"]="chenxuan"; 9 | hash["lover"]="xiaozhu"; 10 | http.gram.body=FileGet::renderHtml("./test.html",hash); 11 | http.gram.typeFile=DealHttp::HTML; 12 | } 13 | int main() 14 | { 15 | DealHttp http; 16 | cout<