├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── conf ├── mime.types └── nginx.conf ├── config.sh ├── flamegraph └── echo.svg ├── http ├── echo │ ├── NdgEchoConf.hpp │ ├── NdgEchoHandler.hpp │ ├── NdgEchoInit.hpp │ ├── NdgEchoModule.cpp │ └── config ├── filter │ ├── NdgFilterConf.hpp │ ├── NdgFilterHandler.hpp │ ├── NdgFilterInit.hpp │ ├── NdgFilterModule.cpp │ └── config ├── test │ ├── NdgTestConf.hpp │ ├── NdgTestHandler.hpp │ ├── NdgTestInit.hpp │ ├── NdgTestModule.cpp │ └── config └── variables │ ├── NdgVariablesConf.hpp │ ├── NdgVariablesHandler.hpp │ ├── NdgVariablesInit.hpp │ ├── NdgVariablesModule.cpp │ └── config ├── legacy ├── datahook │ ├── ModNdgDataHook.cpp │ ├── NdgDataHookConf.hpp │ ├── NdgDataHookHandler.hpp │ ├── NdgDataHookInit.hpp │ └── config ├── echo │ ├── ModNdgEcho.cpp │ ├── NdgEchoConf.hpp │ ├── NdgEchoHandler.hpp │ ├── NdgEchoInit.hpp │ └── config ├── footer │ ├── ModNdgFooter.cpp │ ├── NdgFooterConf.hpp │ ├── NdgFooterHandler.hpp │ ├── NdgFooterInit.hpp │ └── config ├── loadbalance │ ├── ModNdgLoadBalance.cpp │ ├── NdgLoadBalanceConf.hpp │ ├── NdgLoadBalanceHandler.hpp │ ├── NdgLoadBalanceInit.hpp │ └── config ├── shmem │ ├── ModNdgShmem.cpp │ ├── NdgShmemConf.hpp │ ├── NdgShmemHandler.hpp │ ├── NdgShmemInit.hpp │ └── config ├── subrequest │ ├── ModNdgSubrequest.cpp │ ├── NdgSubrequestConf.hpp │ ├── NdgSubrequestHandler.hpp │ ├── NdgSubrequestInit.hpp │ └── config └── upstream │ ├── ModNdgUpstream.cpp │ ├── NdgUpstreamConf.hpp │ ├── NdgUpstreamHandler.hpp │ ├── NdgUpstreamInit.hpp │ └── config ├── ngxpp ├── Nginx.hpp ├── NginxStream.hpp ├── NgxAll.hpp ├── NgxAllocator.hpp ├── NgxArray.hpp ├── NgxBuf.hpp ├── NgxChain.hpp ├── NgxClock.hpp ├── NgxComplexValue.hpp ├── NgxConfig.hpp ├── NgxConnection.hpp ├── NgxCore.hpp ├── NgxCppInc.hpp ├── NgxDatetime.hpp ├── NgxDigest.hpp ├── NgxEvent.hpp ├── NgxException.hpp ├── NgxFilter.hpp ├── NgxGlobal.hpp ├── NgxHeaders.hpp ├── NgxHttpModule.hpp ├── NgxKeyValue.hpp ├── NgxList.hpp ├── NgxLoadBalance.hpp ├── NgxLog.hpp ├── NgxModule.hpp ├── NgxPool.hpp ├── NgxQueue.hpp ├── NgxRbtree.hpp ├── NgxRequest.hpp ├── NgxScript.hpp ├── NgxStreamAll.hpp ├── NgxStreamFilter.hpp ├── NgxStreamModule.hpp ├── NgxStreamSession.hpp ├── NgxString.hpp ├── NgxSubRequest.hpp ├── NgxThread.hpp ├── NgxTimer.hpp ├── NgxUpstream.hpp ├── NgxValue.hpp ├── NgxVariable.hpp ├── NgxWrapper.hpp └── config ├── patch └── auto │ └── make.patch ├── setup ├── boost.sh ├── centos_gcc.sh ├── github.sh └── jemalloc.sh ├── stream ├── discard │ ├── ModNdgStreamDiscard.cpp │ ├── NdgStreamDiscardConf.hpp │ ├── NdgStreamDiscardHandler.hpp │ ├── NdgStreamDiscardInit.hpp │ └── config └── time │ ├── ModNdgStreamTime.cpp │ ├── NdgStreamTimeConf.hpp │ ├── NdgStreamTimeHandler.hpp │ ├── NdgStreamTimeInit.hpp │ └── config └── t ├── echo.t └── filter.t /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | 30 | # tmp 31 | *.swp 32 | *.swo 33 | 34 | # test nginx 35 | servroot/ 36 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | dist: trusty 3 | 4 | os: linux 5 | 6 | notifications: 7 | email: false 8 | 9 | language: cpp 10 | 11 | compiler: 12 | - gcc 13 | - clang 14 | 15 | cache: 16 | cpan: true 17 | apt: true 18 | ccache: true 19 | 20 | env: 21 | global: 22 | - LUAJIT_LIB=/usr/lib64/libluajit-5.1.so 23 | - LUAJIT_INC=/usr/include/luajit-2.0 24 | matrix: 25 | - NGINX_VERSION=1.14.0 26 | - NGINX_VERSION=1.15.7 27 | 28 | before_install: 29 | - sudo apt-get install -qq -y cpanminus libluajit-5.1-dev libgd-dev 30 | - sudo apt-get install libboost-all-dev 31 | - sudo cpanm -v --notest Test::Nginx > build.log 2>&1 || (cat build.log && exit 1) 32 | 33 | install: 34 | - wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz && tar -xzf nginx-${NGINX_VERSION}.tar.gz 35 | #- wget -O boost_1_56_0.tar.gz http://sourceforge.net/projects/boost/files/boost/1.56.0/boost_1_56_0.tar.gz/download && tar -xzf boost_1_56_0.tar.gz 36 | 37 | script: 38 | #- cd boost_1_56_0 39 | #- ./bootstrap.sh --without-libraries=filesystem,graph,iostreams,locale,python,regex,serialization,wave,test,mpi,program_options 40 | #- sudo ./b2 link=static -j2 install > build.log 2>&1 || (cat build.log && exit 1) 41 | #- cd .. 42 | - cd nginx-${NGINX_VERSION}/ 43 | - patch -b ./auto/make ../patch/auto/make.patch 44 | - ./configure 45 | --with-stream 46 | --add-module=../ngxpp 47 | --add-module=../http/echo 48 | --add-module=../http/filter 49 | --add-module=../http/test 50 | --add-module=../http/variables 51 | --add-module=../stream/discard 52 | --add-module=../stream/time 53 | > build.log 2>&1 || (cat build.log && exit 1) 54 | - make -j2 > build.log 2>&1 || (cat build.log && exit 1) 55 | - ./objs/nginx -V 56 | - export PATH=$PATH:`pwd`/objs 57 | - cd .. 58 | - prove -r t 59 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, chronolaw 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Name 2 | ==== 3 | ngx_cpp_dev 4 | 5 | Nginx cpp development kit, with the power of C++11 and Boost Library. 6 | 7 | [![Build Status](https://travis-ci.org/chronolaw/ngx_cpp_dev.svg?branch=master)](https://travis-ci.org/chronolaw/ngx_cpp_dev) 8 | 9 | Table of Contents 10 | ================= 11 | 12 | * [Name](#name) 13 | * [Status](#status) 14 | * [See Also](#see-also) 15 | * [Requirements](#Requirements) 16 | * [Usage](#Usage) 17 | * [Examples](Examples) 18 | * [C++ APIs](#C++-APIs) 19 | * [TODO](#TODO) 20 | 21 | Status 22 | ==== 23 | Experimental but works well. 24 | 25 | Now support *Nginx 1.13.10 and later*. 26 | 27 | See Also 28 | ==== 29 | * [annotated_nginx](https://github.com/chronolaw/annotated_nginx) - 注释nginx,学习研究源码 30 | * [ngx_ansic_dev](https://github.com/chronolaw/ngx_ansic_dev) - Nginc ANSI C Development 31 | * [openresty_dev](https://github.com/chronolaw/openresty_dev) - OpenResty/Lua Programming 32 | * [ngx_google_perftools_profiler](https://github.com/chronolaw/ngx_google_perftools_profiler_module) - A better tools for nginx with google_perftools 33 | 34 | Requirements 35 | ============ 36 | * Linux or other UNIX like 37 | * C++11(gcc 4.6 or later) 38 | * Boost(1.57 or later) 39 | * Nginx 1.13.10 or later 40 | 41 | Please see directiory "setup". 42 | 43 | Usage 44 | ===== 45 | At first, you must patch `nginx/auto/make` to enable g++ compiler and C++11. 46 | 47 | Please see directory *"patch/auto"*. 48 | 49 | For example: 50 | ~~~~ 51 | patch -b make make.patch 52 | ~~~~ 53 | 54 | 55 | Then configure nginx with: 56 | ~~~~ 57 | ./configure --add-module=path/to/ngxpp \ # ngx cpp module 58 | --add-module=xxxx # other modules 59 | make 60 | ~~~~ 61 | 62 | ngx_cpp_module is a pure header library, you should use ngx_cpp_module like this: 63 | ~~~~ 64 | #include "NgxAll.hpp" // include all C++ tools for http modules 65 | ~~~~ 66 | Or 67 | ~~~~ 68 | #include "NgxStreamAll.hpp" // include all C++ tools for stream modules 69 | ~~~~ 70 | 71 | 72 | Examples 73 | ======== 74 | Please see directory *http*, including echo/filter/variables and so on. 75 | 76 | C++ APIs 77 | ======== 78 | 79 | common tools 80 | ------ 81 | 82 | Class Name | Description 83 | ----------------|------------------------ 84 | NgxUnsetValue | generic unset value -1. 85 | NgxValue | wrapper for nginx int, include init/merge/unset. 86 | NgxException | wrapper for nginx error code. 87 | NgxPool | wrapper for nginx memory pool. 88 | NgxAlloctor | adapter to C++ allocator. 89 | NgxString | wrapper for nginx `ngx_str_t`. 90 | NgxClock | wrapper for nginx time functions. 91 | NgxDatetime | wrapper for nginx date functions. 92 | NgxLog | wrapper for nginx error log. 93 | 94 | data structure 95 | ------ 96 | 97 | Class Name | Description 98 | ----------------|------------------------ 99 | NgxArray | wrapper for nginx `ngx_array_t`. 100 | NgxList | wrapper for nginx `ngx_list_t.` 101 | NgxQueue | wrapper for nginx `ngx_queue_t`. 102 | NgxBuf | deprecated, wrapper for nginx `ngx_buf_t`. 103 | NgxChain | deprecated, wrapper for nginx `ngx_chain_t`. 104 | NgxRbtree | wrapper for nginx `ngx_rbtree_t`. 105 | 106 | modules 107 | ------ 108 | 109 | Class Name | Description 110 | ----------------|------------------------ 111 | NgxModuleConfig | easy to access nginx module confing info. 112 | NgxModule | get module's config and ctx data. 113 | NgxCommand | deprecated, DO NOT USE IT. 114 | NgxTake | deprecated 115 | NgxModuleCtx | easy to access nginx module's ctx data. 116 | NgxHttpCoreModule|wrapper for ngx_http_core_module 117 | NgxFilter | wrapper for nginx filter mechanism. 118 | 119 | http process 120 | ------ 121 | 122 | Class Name | Description 123 | ----------------|------------------------ 124 | NgxHeaders | 125 | NgxRequest | 126 | NgxResponse | 127 | NgxUpstreamHelper| 128 | NgxLoadBalance | 129 | NgxSubRequest | 130 | 131 | others 132 | ------ 133 | Class Name | Description 134 | ----------------|------------------------ 135 | NgxVariables | 136 | NgxVarManager | 137 | NgxDigest | 138 | NgxTimer | 139 | 140 | TODO 141 | ==== 142 | * more test suites 143 | * nginx datagram 144 | * ... 145 | -------------------------------------------------------------------------------- /conf/mime.types: -------------------------------------------------------------------------------- 1 | 2 | types { 3 | text/html html htm shtml; 4 | text/css css; 5 | text/xml xml; 6 | image/gif gif; 7 | image/jpeg jpeg jpg; 8 | application/javascript js; 9 | application/atom+xml atom; 10 | application/rss+xml rss; 11 | 12 | text/mathml mml; 13 | text/plain txt; 14 | text/vnd.sun.j2me.app-descriptor jad; 15 | text/vnd.wap.wml wml; 16 | text/x-component htc; 17 | 18 | image/png png; 19 | image/tiff tif tiff; 20 | image/vnd.wap.wbmp wbmp; 21 | image/x-icon ico; 22 | image/x-jng jng; 23 | image/x-ms-bmp bmp; 24 | image/svg+xml svg svgz; 25 | image/webp webp; 26 | 27 | application/font-woff woff; 28 | application/java-archive jar war ear; 29 | application/json json; 30 | application/mac-binhex40 hqx; 31 | application/msword doc; 32 | application/pdf pdf; 33 | application/postscript ps eps ai; 34 | application/rtf rtf; 35 | application/vnd.apple.mpegurl m3u8; 36 | application/vnd.ms-excel xls; 37 | application/vnd.ms-fontobject eot; 38 | application/vnd.ms-powerpoint ppt; 39 | application/vnd.wap.wmlc wmlc; 40 | application/vnd.google-earth.kml+xml kml; 41 | application/vnd.google-earth.kmz kmz; 42 | application/x-7z-compressed 7z; 43 | application/x-cocoa cco; 44 | application/x-java-archive-diff jardiff; 45 | application/x-java-jnlp-file jnlp; 46 | application/x-makeself run; 47 | application/x-perl pl pm; 48 | application/x-pilot prc pdb; 49 | application/x-rar-compressed rar; 50 | application/x-redhat-package-manager rpm; 51 | application/x-sea sea; 52 | application/x-shockwave-flash swf; 53 | application/x-stuffit sit; 54 | application/x-tcl tcl tk; 55 | application/x-x509-ca-cert der pem crt; 56 | application/x-xpinstall xpi; 57 | application/xhtml+xml xhtml; 58 | application/xspf+xml xspf; 59 | application/zip zip; 60 | 61 | application/octet-stream bin exe dll; 62 | application/octet-stream deb; 63 | application/octet-stream dmg; 64 | application/octet-stream iso img; 65 | application/octet-stream msi msp msm; 66 | 67 | application/vnd.openxmlformats-officedocument.wordprocessingml.document docx; 68 | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx; 69 | application/vnd.openxmlformats-officedocument.presentationml.presentation pptx; 70 | 71 | audio/midi mid midi kar; 72 | audio/mpeg mp3; 73 | audio/ogg ogg; 74 | audio/x-m4a m4a; 75 | audio/x-realaudio ra; 76 | 77 | video/3gpp 3gpp 3gp; 78 | video/mp2t ts; 79 | video/mp4 mp4; 80 | video/mpeg mpeg mpg; 81 | video/quicktime mov; 82 | video/webm webm; 83 | video/x-flv flv; 84 | video/x-m4v m4v; 85 | video/x-mng mng; 86 | video/x-ms-asf asx asf; 87 | video/x-ms-wmv wmv; 88 | video/x-msvideo avi; 89 | } 90 | -------------------------------------------------------------------------------- /conf/nginx.conf: -------------------------------------------------------------------------------- 1 | 2 | master_process off; 3 | daemon off; 4 | 5 | #user nobody; 6 | worker_processes 1; 7 | 8 | #error_log logs/error.log; 9 | #error_log logs/error.log notice; 10 | #error_log logs/error.log info; 11 | 12 | #pid logs/nginx.pid; 13 | 14 | 15 | events { 16 | worker_connections 1024; 17 | } 18 | 19 | 20 | http { 21 | include mime.types; 22 | default_type application/octet-stream; 23 | 24 | #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 25 | # '$status $body_bytes_sent "$http_referer" ' 26 | # '"$http_user_agent" "$http_x_forwarded_for"'; 27 | 28 | #access_log logs/access.log main; 29 | 30 | sendfile on; 31 | 32 | keepalive_timeout 60; 33 | 34 | #shared memory 35 | ndg_shmem_size 2k; 36 | 37 | #main server 38 | server { 39 | listen 80; 40 | server_name localhost; 41 | 42 | #charset koi8-r; 43 | 44 | #access_log logs/host.access.log main; 45 | 46 | set $var1 "xyz-abc"; 47 | 48 | location /test { 49 | ndg_test on; 50 | 51 | alias /usr/local/nginx/html; 52 | index index.html index.htm; 53 | } 54 | 55 | location /echo { 56 | ndg_echo "hello nginx\n"; 57 | 58 | ndg_header x-name chrono; 59 | ndg_header x-value trigger; 60 | ndg_footer "ocarina of time\n"; 61 | } 62 | 63 | location /hello { 64 | ndg_echo "hello"; 65 | 66 | ndg_header x-name chrono; 67 | ndg_footer "\n"; 68 | } 69 | 70 | #location /sub { 71 | # ndg_subrequest_loc "/hello"; 72 | # ndg_subrequest_args "chrono"; 73 | 74 | # add_header x-rtt $rtt; 75 | # ndg_footer "\n"; 76 | #} 77 | 78 | location / { 79 | root html; 80 | index index.html index.htm; 81 | } 82 | 83 | } 84 | 85 | #server { 86 | # listen 88; 87 | # server_name localhost; 88 | 89 | # location / { 90 | # proxy_set_header Host $host; 91 | # proxy_pass http://localhost:80; 92 | # } 93 | #} 94 | 95 | #upstream block 96 | #upstream backend{ 97 | # ndg_load_balance; 98 | # server 127.0.0.1:2017; 99 | # #server localhost:88; 100 | #} 101 | 102 | #upstream proxy pass 103 | #server { 104 | # listen 8080; 105 | # server_name localhost; 106 | 107 | # location / { 108 | # ndg_upstream_pass backend; 109 | # } 110 | #} 111 | } 112 | -------------------------------------------------------------------------------- /config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ngx_path=$HOME/nginx 4 | src_path=$HOME/github/ngx_cpp_dev 5 | 6 | build_date="${USER} build at `date '+%Y.%m.%d %H:%M'`" 7 | cc_opt="-g -O0" 8 | common_opts="--with-threads --with-pcre-jit" 9 | prefix="--prefix=/opt/nginx_cpp" 10 | 11 | ngxpp_module="--add-module=${src_path}/ngxpp" 12 | 13 | modules="test echo filter 14 | variables 15 | " 16 | 17 | http_modules="" 18 | 19 | for m in $modules 20 | do 21 | http_modules="${http_modules} --add-module=${src_path}/http/${m} " 22 | done 23 | 24 | modules="" 25 | 26 | event_modules="" 27 | 28 | for m in $modules 29 | do 30 | event_modules="${event_modules} --add-module=${src_path}/event/${m} " 31 | done 32 | 33 | opts="${prefix} 34 | ${common_opts} 35 | ${ngxpp_module} 36 | ${http_modules} 37 | ${event_modules} 38 | " 39 | cd $ngx_path 40 | 41 | ./configure \ 42 | --build="${build_date}" \ 43 | --with-cc-opt="${cc_opt}" \ 44 | ${opts} 45 | 46 | # --with-ld-opt="-lrt" 47 | 48 | cd - 49 | -------------------------------------------------------------------------------- /http/echo/NdgEchoConf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2018 2 | // Author: Chrono Law 3 | #ifndef _NDG_ECHO_CONF_HPP 4 | #define _NDG_ECHO_CONF_HPP 5 | 6 | #include "NgxAll.hpp" 7 | 8 | class NdgEchoConf final 9 | { 10 | public: 11 | typedef NdgEchoConf this_type; 12 | public: 13 | NdgEchoConf() = default; 14 | ~NdgEchoConf() = default; 15 | public: 16 | ngx_str_t msg; 17 | public: 18 | static void* create(ngx_conf_t* cf) 19 | { 20 | return NgxPool(cf).alloc(); 21 | } 22 | 23 | static this_type& cast(void* conf) 24 | { 25 | return *reinterpret_cast(conf); 26 | } 27 | }; 28 | 29 | NGX_MOD_INSTANCE(NdgEchoModule, ngx_http_ndg_echo_module, NdgEchoConf) 30 | 31 | #endif //_NDG_ECHO_CONF_HPP 32 | -------------------------------------------------------------------------------- /http/echo/NdgEchoHandler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2018 2 | // Author: Chrono Law 3 | #ifndef _NDG_ECHO_HANDLER_HPP 4 | #define _NDG_ECHO_HANDLER_HPP 5 | 6 | #include 7 | 8 | #include "NdgEchoConf.hpp" 9 | 10 | class NdgEchoHandler final 11 | { 12 | public: 13 | typedef NdgEchoHandler this_type; 14 | typedef NdgEchoModule this_module; 15 | public: 16 | static ngx_int_t handler(ngx_http_request_t *r) 17 | try 18 | { 19 | using namespace std; 20 | 21 | NgxRequest req(r); 22 | 23 | if(!req.method(NGX_HTTP_GET)) 24 | { 25 | return NGX_HTTP_NOT_ALLOWED; 26 | } 27 | 28 | req.body().discard(); 29 | 30 | auto& cf = this_module::conf().loc(r); 31 | 32 | NgxString msg = cf.msg; 33 | 34 | // check args 35 | NgxString args = req->args; 36 | 37 | auto len = msg.size(); 38 | if(!args.empty()) 39 | { 40 | len += args.size() + 1; 41 | } 42 | 43 | NgxResponse resp(r); 44 | 45 | //auto h = resp.headers(); 46 | 47 | resp.length(len); 48 | resp.status(NGX_HTTP_OK); 49 | 50 | if(!args.empty()) 51 | { 52 | resp.send(args); 53 | resp.send(","); 54 | } 55 | 56 | resp.send(msg); 57 | 58 | return resp.eof(); 59 | } 60 | catch(const NgxException& e) 61 | { 62 | return e.code(); 63 | } 64 | }; 65 | 66 | #endif //_NDG_ECHO_HANDLER_HPP 67 | -------------------------------------------------------------------------------- /http/echo/NdgEchoInit.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_ECHO_INIT_HPP 4 | #define _NDG_ECHO_INIT_HPP 5 | 6 | #include "NdgEchoConf.hpp" 7 | #include "NdgEchoHandler.hpp" 8 | 9 | class NdgEchoInit final 10 | { 11 | public: 12 | typedef NdgEchoConf conf_type; 13 | typedef NdgEchoHandler handler_type; 14 | typedef NdgEchoInit this_type; 15 | public: 16 | static ngx_command_t* cmds() 17 | { 18 | static ngx_command_t n[] = 19 | { 20 | { 21 | ngx_string("ndg_echo"), 22 | NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 23 | &this_type::set_echo, 24 | NGX_HTTP_LOC_CONF_OFFSET, 25 | offsetof(conf_type, msg), 26 | nullptr 27 | }, 28 | 29 | ngx_null_command 30 | }; 31 | 32 | return n; 33 | } 34 | public: 35 | static ngx_http_module_t* ctx() 36 | { 37 | static ngx_http_module_t c = 38 | { 39 | NGX_MODULE_NULL(6), 40 | &conf_type::create, 41 | NGX_MODULE_NULL(1), 42 | }; 43 | 44 | return &c; 45 | } 46 | public: 47 | static const ngx_module_t& module() 48 | { 49 | static ngx_module_t m = 50 | { 51 | NGX_MODULE_V1, 52 | 53 | ctx(), 54 | cmds(), 55 | 56 | NGX_HTTP_MODULE, 57 | NGX_MODULE_NULL(7), 58 | NGX_MODULE_V1_PADDING 59 | }; 60 | 61 | return m; 62 | } 63 | private: 64 | static char* set_echo(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) 65 | { 66 | auto rc = ngx_conf_set_str_slot(cf, cmd, conf); 67 | 68 | if(rc != NGX_CONF_OK) 69 | { 70 | return rc; 71 | } 72 | 73 | NgxHttpCoreModule::handler( 74 | cf, &handler_type::handler); 75 | 76 | return NGX_CONF_OK; 77 | } 78 | }; 79 | 80 | #endif //_NDG_ECHO_INIT_HPP 81 | -------------------------------------------------------------------------------- /http/echo/NdgEchoModule.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | 4 | #include "NdgEchoInit.hpp" 5 | 6 | auto ngx_http_ndg_echo_module = NdgEchoInit::module(); 7 | 8 | -------------------------------------------------------------------------------- /http/echo/config: -------------------------------------------------------------------------------- 1 | #./configure --add-module=$HOME/ngx_cpp_dev/modules/echo 2 | 3 | ngx_addon_name=ngx_http_ndg_echo_module 4 | 5 | 6 | if test -n "$ngx_module_link"; then 7 | ngx_module_type=HTTP 8 | ngx_module_name=ngx_http_ndg_echo_module 9 | ngx_module_srcs="$ngx_addon_dir/NdgEchoModule.cpp" 10 | 11 | . auto/module 12 | else 13 | HTTP_MODULES="$HTTP_MODULES ngx_http_ndg_echo_module" 14 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/NdgEchoModule.cpp" 15 | fi 16 | 17 | -------------------------------------------------------------------------------- /http/filter/NdgFilterConf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2018 2 | // Author: Chrono Law 3 | #ifndef _NDG_FILTER_CONF_HPP 4 | #define _NDG_FILTER_CONF_HPP 5 | 6 | #include "NgxAll.hpp" 7 | 8 | class NdgFilterConf final 9 | { 10 | public: 11 | typedef NdgFilterConf this_type; 12 | public: 13 | NdgFilterConf() = default; 14 | ~NdgFilterConf() = default; 15 | public: 16 | ngx_array_t* headers; 17 | ngx_str_t footer; 18 | public: 19 | static void* create(ngx_conf_t* cf) 20 | { 21 | return NgxPool(cf).alloc(); 22 | } 23 | 24 | }; 25 | 26 | struct NdgFilterCtx final 27 | { 28 | int flag = 0; 29 | }; 30 | 31 | NGX_MOD_CTX_INSTANCE(NdgFilterModule, ngx_http_ndg_filter_module, NdgFilterCtx, NdgFilterConf) 32 | 33 | #endif //_NDG_FILTER_CONF_HPP 34 | -------------------------------------------------------------------------------- /http/filter/NdgFilterHandler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2018 2 | // Author: Chrono Law 3 | #ifndef _NDG_FILTER_HANDLER_HPP 4 | #define _NDG_FILTER_HANDLER_HPP 5 | 6 | #include "NdgFilterConf.hpp" 7 | 8 | class NdgFilterHandler final 9 | { 10 | public: 11 | typedef NdgFilterHandler this_type; 12 | typedef NdgFilterModule this_module; 13 | typedef NgxFilter this_filter; 14 | public: 15 | static ngx_int_t init(ngx_conf_t* cf) 16 | { 17 | this_filter::init(&this_type::header_filter, &this_type::body_filter); 18 | return NGX_OK; 19 | } 20 | public: 21 | static ngx_int_t header_filter(ngx_http_request_t *r) 22 | try 23 | { 24 | do_header_filter(r); 25 | return this_filter::next(r); 26 | } 27 | catch(const NgxException& e) 28 | { 29 | return e.code(); 30 | } 31 | 32 | static void do_header_filter(ngx_http_request_t *r) 33 | { 34 | auto& ctx = this_module::data(r); 35 | if(ctx.flag) 36 | { 37 | return; 38 | } 39 | 40 | ctx.flag = 1; 41 | NgxResponse resp(r); 42 | 43 | auto& cf = this_module::conf().loc(r); 44 | 45 | NgxKvArray headers = cf.headers; 46 | 47 | for(auto i = 0u; i < headers.size();++i) 48 | { 49 | auto& header = headers[i]; 50 | 51 | ngx_table_elt_t kv; 52 | 53 | kv.hash = 1; 54 | kv.key = header.key; 55 | kv.value = header.value; 56 | 57 | resp.headers().add(kv); 58 | } 59 | 60 | // check r->header_only r->method & NGX_HTTP_HEAD 61 | NgxString footer = cf.footer; 62 | if(footer.empty()) 63 | { 64 | return; 65 | } 66 | 67 | auto len = resp->headers_out.content_length_n; 68 | if(len > 0) 69 | { 70 | resp.length(len + footer.size()); 71 | } 72 | } 73 | 74 | public: 75 | static ngx_int_t body_filter(ngx_http_request_t *r, ngx_chain_t *in) 76 | try 77 | { 78 | do_body_filter(r, in); 79 | return this_filter::next(r, in); 80 | } 81 | catch(const NgxException& e) 82 | { 83 | return e.code(); 84 | } 85 | 86 | static void do_body_filter(ngx_http_request_t *r, ngx_chain_t *in) 87 | { 88 | auto& cf = this_module::conf().loc(r); 89 | 90 | NgxString footer = cf.footer; 91 | if(footer.empty()) 92 | { 93 | return; 94 | } 95 | 96 | auto& ctx = this_module::data(r); 97 | if(ctx.flag != 1) 98 | { 99 | return; 100 | } 101 | 102 | auto p = in; 103 | for (; p; p = p->next) { 104 | if (p->buf->last_buf) { 105 | break; 106 | } 107 | } 108 | 109 | // eof not find 110 | if (p == NULL) { 111 | return; 112 | } 113 | 114 | ctx.flag = 2; 115 | 116 | NgxPool pool(r); 117 | 118 | auto b = pool.buffer(); 119 | 120 | b->pos = cf.footer.data; 121 | b->last = cf.footer.data + cf.footer.len; 122 | b->memory = 1; 123 | b->last_buf = 1; 124 | b->last_in_chain = 1; 125 | 126 | // set to the last node 127 | if (ngx_buf_size(p->buf) == 0) { 128 | p->buf = b; 129 | return; 130 | } 131 | 132 | // add a new last node 133 | auto out = pool.chain(); 134 | out->buf = b; 135 | out->next = NULL; 136 | 137 | // link to the new node 138 | p->next = out; 139 | p->buf->last_buf = 0; 140 | p->buf->last_in_chain = 0; 141 | 142 | return; //to next filter 143 | } 144 | }; 145 | 146 | #endif //_NDG_FILTER_HANDLER_HPP 147 | -------------------------------------------------------------------------------- /http/filter/NdgFilterInit.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2018 2 | // Author: Chrono Law 3 | #ifndef _NDG_FILTER_INIT_HPP 4 | #define _NDG_FILTER_INIT_HPP 5 | 6 | #include "NdgFilterConf.hpp" 7 | #include "NdgFilterHandler.hpp" 8 | 9 | class NdgFilterInit final 10 | { 11 | public: 12 | typedef NdgFilterConf conf_type; 13 | typedef NdgFilterHandler handler_type; 14 | typedef NdgFilterInit this_type; 15 | public: 16 | static ngx_command_t* cmds() 17 | { 18 | static ngx_command_t n[] = 19 | { 20 | { 21 | ngx_string("ndg_header"), 22 | NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, 23 | ngx_conf_set_keyval_slot, 24 | NGX_HTTP_LOC_CONF_OFFSET, 25 | offsetof(conf_type, headers), 26 | nullptr 27 | }, 28 | 29 | { 30 | ngx_string("ndg_footer"), 31 | NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 32 | ngx_conf_set_str_slot, 33 | NGX_HTTP_LOC_CONF_OFFSET, 34 | offsetof(conf_type, footer), 35 | nullptr 36 | }, 37 | 38 | ngx_null_command 39 | }; 40 | 41 | return n; 42 | } 43 | public: 44 | static ngx_http_module_t* ctx() 45 | { 46 | static ngx_http_module_t c = 47 | { 48 | NGX_MODULE_NULL(1), 49 | &handler_type::init, 50 | NGX_MODULE_NULL(4), 51 | &conf_type::create, 52 | NGX_MODULE_NULL(1), 53 | }; 54 | 55 | return &c; 56 | } 57 | public: 58 | static const ngx_module_t& module() 59 | { 60 | static ngx_module_t m = 61 | { 62 | NGX_MODULE_V1, 63 | 64 | ctx(), 65 | cmds(), 66 | 67 | NGX_HTTP_MODULE, 68 | NGX_MODULE_NULL(7), 69 | NGX_MODULE_V1_PADDING 70 | }; 71 | 72 | return m; 73 | } 74 | }; 75 | 76 | #endif //_NDG_FILTER_INIT_HPP 77 | -------------------------------------------------------------------------------- /http/filter/NdgFilterModule.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 2 | // Author: Chrono Law 3 | 4 | #include "NdgFilterInit.hpp" 5 | 6 | auto ngx_http_ndg_filter_module = NdgFilterInit::module(); 7 | 8 | -------------------------------------------------------------------------------- /http/filter/config: -------------------------------------------------------------------------------- 1 | #./configure --add-module=$HOME/ngx_cpp_dev/modules/footer 2 | 3 | ngx_addon_name=ngx_http_ndg_filter_module 4 | 5 | if test -n "$ngx_module_link"; then 6 | ngx_module_type=HTTP_FILTER 7 | ngx_module_name=ngx_http_ndg_filter_module 8 | ngx_module_srcs="$ngx_addon_dir/NdgFilterModule.cpp" 9 | 10 | . auto/module 11 | else 12 | HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES ngx_http_ndg_filter_module" 13 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/NdgFilterModule.cpp" 14 | fi 15 | -------------------------------------------------------------------------------- /http/test/NdgTestConf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 2 | // Author: Chrono Law 3 | #ifndef _NDG_TEST_CONF_HPP 4 | #define _NDG_TEST_CONF_HPP 5 | 6 | #include "NgxAll.hpp" 7 | 8 | class NdgTestConf final 9 | { 10 | public: 11 | typedef NdgTestConf this_type; 12 | public: 13 | NdgTestConf() = default; 14 | ~NdgTestConf() = default; 15 | public: 16 | ngx_flag_t enabled = NgxUnsetValue::get(); 17 | public: 18 | static void* create(ngx_conf_t* cf) 19 | { 20 | return NgxPool(cf).alloc(); 21 | } 22 | 23 | static char* merge(ngx_conf_t *cf, void *parent, void *child) 24 | { 25 | boost::ignore_unused(cf); 26 | 27 | auto prev = reinterpret_cast(parent); 28 | auto conf = reinterpret_cast(child); 29 | 30 | NgxValue::merge(conf->enabled, prev->enabled, 0); 31 | 32 | return NGX_CONF_OK; 33 | } 34 | }; 35 | 36 | NGX_MOD_INSTANCE(NdgTestModule, ndg_test_module, NdgTestConf) 37 | 38 | #endif //_NDG_TEST_CONF_HPP 39 | -------------------------------------------------------------------------------- /http/test/NdgTestInit.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 2 | // Author: Chrono Law 3 | #ifndef _NDG_TEST_INIT_HPP 4 | #define _NDG_TEST_INIT_HPP 5 | 6 | #include "NdgTestConf.hpp" 7 | #include "NdgTestHandler.hpp" 8 | 9 | class NdgTestInit final 10 | { 11 | public: 12 | typedef NdgTestConf conf_type; 13 | typedef NdgTestHandler handler_type; 14 | typedef NdgTestInit this_type; 15 | public: 16 | static ngx_command_t* cmds() 17 | { 18 | static ngx_command_t n[] = 19 | { 20 | { 21 | ngx_string("ndg_test"), 22 | NgxTake(NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, 1), 23 | ngx_conf_set_flag_slot, 24 | NGX_HTTP_LOC_CONF_OFFSET, 25 | offsetof(conf_type, enabled), 26 | 0 27 | }, 28 | 29 | ngx_null_command 30 | }; 31 | 32 | return n; 33 | } 34 | public: 35 | static ngx_http_module_t* ctx() 36 | { 37 | static ngx_http_module_t c = 38 | { 39 | NGX_MODULE_NULL(1), 40 | 41 | &handler_type::init, 42 | 43 | NGX_MODULE_NULL(4), 44 | 45 | &conf_type::create, 46 | &conf_type::merge, 47 | }; 48 | 49 | return &c; 50 | } 51 | public: 52 | static const ngx_module_t& module() 53 | { 54 | static ngx_module_t m = 55 | { 56 | NGX_MODULE_V1, 57 | 58 | ctx(), 59 | cmds(), 60 | 61 | NGX_HTTP_MODULE, 62 | NGX_MODULE_NULL(7), 63 | NGX_MODULE_V1_PADDING 64 | }; 65 | 66 | return m; 67 | } 68 | }; 69 | 70 | #endif //_NDG_TEST_INIT_HPP 71 | 72 | -------------------------------------------------------------------------------- /http/test/NdgTestModule.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 2 | // Author: Chrono Law 3 | #include "NdgTestInit.hpp" 4 | 5 | auto ndg_test_module = NdgTestInit::module(); 6 | 7 | /* 8 | #include 9 | 10 | #include "NgxAll.hpp" 11 | 12 | struct NdgTestConf final 13 | { 14 | ngx_flag_t enabled = NgxUnsetValue::get(); 15 | }; 16 | 17 | static void *create(ngx_conf_t* cf); 18 | static char *merge(ngx_conf_t *cf, void *parent, void *child); 19 | 20 | static ngx_command_t ndg_test_cmds[] = 21 | { 22 | { 23 | ngx_string("ndg_test"), 24 | NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, 25 | ngx_conf_set_flag_slot, 26 | NGX_HTTP_LOC_CONF_OFFSET, 27 | offsetof(NdgTestConf, enabled), 28 | nullptr 29 | }, 30 | 31 | ngx_null_command 32 | }; 33 | 34 | static ngx_int_t init(ngx_conf_t* cf); 35 | static ngx_int_t handler(ngx_http_request_t *r); 36 | 37 | static ngx_http_module_t ndg_test_ctx = 38 | { 39 | nullptr, 40 | init, 41 | nullptr, 42 | nullptr, 43 | nullptr, 44 | nullptr, 45 | create, 46 | nullptr,//merge 47 | }; 48 | 49 | ngx_module_t ndg_test_module = 50 | { 51 | NGX_MODULE_V1, 52 | &ndg_test_ctx, 53 | ndg_test_cmds, 54 | NGX_HTTP_MODULE, 55 | nullptr, // init master 56 | nullptr, // init module 57 | nullptr, // init process 58 | nullptr, // init thread 59 | nullptr, // exit thread 60 | nullptr, // exit process 61 | nullptr, // exit master 62 | NGX_MODULE_V1_PADDING 63 | }; 64 | 65 | static void* create(ngx_conf_t* cf) 66 | { 67 | return NgxPool(cf).alloc(); 68 | } 69 | 70 | static char *merge(ngx_conf_t *cf, void *parent, void *child) 71 | { 72 | boost::ignore_unused(cf); 73 | 74 | auto prev = reinterpret_cast(parent); 75 | auto conf = reinterpret_cast(child); 76 | 77 | NgxValue::merge(conf->enabled, prev->enabled, 1); 78 | 79 | return NGX_CONF_OK; 80 | } 81 | 82 | static ngx_int_t init(ngx_conf_t* cf) 83 | { 84 | auto cmcf = reinterpret_cast( 85 | ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module)); 86 | 87 | NgxArray arr( 88 | cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers); 89 | 90 | arr.push(handler); 91 | 92 | return NGX_OK; 93 | } 94 | 95 | static ngx_int_t handler(ngx_http_request_t *r) 96 | { 97 | auto cf = reinterpret_cast( 98 | ngx_http_get_module_loc_conf(r, ndg_test_module)); 99 | 100 | NgxLogError(r).print("hello c++"); 101 | 102 | if (cf->enabled) 103 | { 104 | std::cout << "hello nginx" << std::endl; 105 | } 106 | else 107 | { 108 | std::cout << "hello disabled" << std::endl; 109 | } 110 | 111 | 112 | return NGX_DECLINED; 113 | } 114 | */ 115 | 116 | -------------------------------------------------------------------------------- /http/test/config: -------------------------------------------------------------------------------- 1 | #./configure --add-module=$HOME/ngx_cpp_dev/modules/test 2 | 3 | ngx_addon_name=ndg_test_module 4 | 5 | if test -n "$ngx_module_link"; then 6 | ngx_module_type=HTTP 7 | ngx_module_name=ndg_test_module 8 | ngx_module_srcs="$ngx_addon_dir/NdgTestModule.cpp" 9 | 10 | . auto/module 11 | else 12 | HTTP_MODULES="$HTTP_MODULES ndg_test_module" 13 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/NdgTestModule.cpp" 14 | fi 15 | 16 | #HTTP_MODULES="$HTTP_MODULES ndg_test_module" 17 | #NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ModNdgTest.cpp" 18 | #HTTP_INCS="$HTTP_INCS $ngx_addon_dir/../../ngxpp" 19 | 20 | #CORE_LIBS="$CORE_LIBS -lboost_date_time" 21 | 22 | ############# 23 | 24 | #ndg_addon_mod=ndg_test_module 25 | #ndg_addon_src=ModNdgTest.cpp 26 | #ndg_addon_incs="$ngx_addon_dir/../../ngxpp" 27 | 28 | #HTTP_MODULES="$HTTP_MODULES $ndg_addon_mod" 29 | #HTTP_AUX_FILTER_MODULES="$HTTP_AUX_FILTER_MODULES $ndg_addon_name" 30 | 31 | #NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/$ndg_addon_src" 32 | 33 | #HTTP_INCS="$HTTP_INCS $ndg_addon_incs" 34 | #CORE_LIBS="$CORE_LIBS $ndg_addon_libs" 35 | -------------------------------------------------------------------------------- /http/variables/NdgVariablesConf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 2 | // Author: Chrono Law 3 | #ifndef _NDG_VARIABLES_CONF_HPP 4 | #define _NDG_VARIABLES_CONF_HPP 5 | 6 | #include "NgxAll.hpp" 7 | 8 | #endif //_NDG_VARIABLES_CONF_HPP 9 | -------------------------------------------------------------------------------- /http/variables/NdgVariablesHandler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_VARIABLES_HANDLER_HPP 4 | #define _NDG_VARIABLES_HANDLER_HPP 5 | 6 | #include "NdgVariablesConf.hpp" 7 | 8 | class NdgVariablesHandler final 9 | { 10 | public: 11 | typedef NdgVariablesHandler this_type; 12 | public: 13 | static ngx_http_variable_t* get_vars() 14 | { 15 | static ngx_http_variable_t vars[] = { 16 | 17 | { ngx_string("today"), nullptr, 18 | &this_type::get_today, 0, 0, 0 }, 19 | 20 | { ngx_string("rtt"), nullptr, 21 | &this_type::get_rtt, 0, 22 | NGX_HTTP_VAR_NOCACHEABLE, 0 }, 23 | 24 | { ngx_string("current_method"), nullptr, 25 | &this_type::get_current_method, 0, 26 | NGX_HTTP_VAR_NOCACHEABLE, 0 }, 27 | 28 | { ngx_string("parsed_uri"), nullptr, 29 | &this_type::get_parsed_uri, 0, 30 | NGX_HTTP_VAR_NOCACHEABLE, 0 }, 31 | 32 | { ngx_null_string, nullptr, nullptr, 0, 0, 0 } 33 | }; 34 | 35 | return vars; 36 | } 37 | public: 38 | static ngx_int_t get_rtt( 39 | ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) 40 | { 41 | boost::ignore_unused(data); 42 | 43 | auto sockfd = r->connection->fd; 44 | 45 | tcp_info info; 46 | socklen_t len = sizeof(info); 47 | 48 | auto rc = getsockopt(sockfd, SOL_TCP, TCP_INFO, &info, &len); 49 | assert(!rc); 50 | 51 | auto buf = NgxPool(r).nalloc(10); 52 | ngx_str_t str{10, buf}; 53 | 54 | NgxString(str).printf("%d", info.tcpi_rtt / 1000); 55 | 56 | NgxVariableValue(v).set(str); 57 | 58 | return NGX_OK; 59 | } 60 | public: 61 | static ngx_int_t get_today( 62 | ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) 63 | { 64 | boost::ignore_unused(data); 65 | 66 | auto str = NgxDatetime::today(); 67 | 68 | NgxVariableValue(v).set(str); 69 | 70 | return NGX_OK; 71 | } 72 | 73 | static ngx_int_t get_current_method( 74 | ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) 75 | { 76 | boost::ignore_unused(data); 77 | 78 | NgxVariableValue(v).set(r->method_name); 79 | 80 | return NGX_OK; 81 | } 82 | 83 | static ngx_int_t get_parsed_uri( 84 | ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) 85 | { 86 | boost::ignore_unused(data); 87 | 88 | NgxVariableValue(v).set(r->uri); 89 | 90 | return NGX_OK; 91 | } 92 | }; 93 | 94 | #endif //_NDG_VARIABLES_HANDLER_HPP 95 | -------------------------------------------------------------------------------- /http/variables/NdgVariablesInit.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 2 | // Author: Chrono Law 3 | #ifndef _NDG_VARIABLES_INIT_HPP 4 | #define _NDG_VARIABLES_INIT_HPP 5 | 6 | #include "NdgVariablesConf.hpp" 7 | #include "NdgVariablesHandler.hpp" 8 | 9 | class NdgVariablesInit final 10 | { 11 | public: 12 | typedef NdgVariablesHandler handler_type; 13 | typedef NdgVariablesInit this_type; 14 | 15 | typedef NgxVariables<&handler_type::get_vars> 16 | these_variables; 17 | public: 18 | static ngx_http_module_t* ctx() 19 | { 20 | static ngx_http_module_t c = 21 | { 22 | &these_variables::init, 23 | NGX_MODULE_NULL(7) 24 | }; 25 | 26 | return &c; 27 | } 28 | public: 29 | static const ngx_module_t& module() 30 | { 31 | static ngx_module_t m = 32 | { 33 | NGX_MODULE_V1, 34 | 35 | ctx(), 36 | NGX_MODULE_NULL(1), 37 | 38 | NGX_HTTP_MODULE, 39 | NGX_MODULE_NULL(7), 40 | NGX_MODULE_V1_PADDING 41 | }; 42 | 43 | return m; 44 | } 45 | }; 46 | 47 | #endif //_NDG_VARIABLES_INIT_HPP 48 | -------------------------------------------------------------------------------- /http/variables/NdgVariablesModule.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 2 | // Author: Chrono Law 3 | 4 | #include "NdgVariablesInit.hpp" 5 | 6 | auto ndg_variables_module = NdgVariablesInit::module(); 7 | 8 | -------------------------------------------------------------------------------- /http/variables/config: -------------------------------------------------------------------------------- 1 | #./configure --add-module=$HOME/ngx_cpp_dev/modules/variables 2 | 3 | ngx_addon_name=ndg_variables_module 4 | 5 | if test -n "$ngx_module_link"; then 6 | ngx_module_type=HTTP 7 | ngx_module_name=ndg_variables_module 8 | ngx_module_srcs="$ngx_addon_dir/NdgVariablesModule.cpp" 9 | 10 | . auto/module 11 | else 12 | HTTP_MODULES="$HTTP_MODULES ndg_variables_module" 13 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/NdgVariablesModule.cpp" 14 | fi 15 | -------------------------------------------------------------------------------- /legacy/datahook/ModNdgDataHook.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 2 | // Author: Chrono Law 3 | 4 | #include "NdgDataHookInit.hpp" 5 | 6 | auto ndg_data_hook_module = NdgDataHookInit::module(); 7 | 8 | -------------------------------------------------------------------------------- /legacy/datahook/NdgDataHookConf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_DATA_HOOK_CONF_HPP 4 | #define _NDG_DATA_HOOK_CONF_HPP 5 | 6 | #include "NgxAll.hpp" 7 | 8 | struct NdgDataHookCtx final 9 | { 10 | public: 11 | ngx_flag_t hook = false; 12 | 13 | ngx_int_t status = 0; 14 | ngx_http_headers_out_t* headers = nullptr; 15 | ngx_chain_t* body = nullptr; 16 | 17 | ngx_flag_t do_hook = false; 18 | public: 19 | void hooking() 20 | { 21 | hook = true; 22 | status = 0; 23 | headers = nullptr; 24 | body = nullptr; 25 | } 26 | 27 | void state(ngx_int_t rc) 28 | { 29 | if(status) 30 | { 31 | return; 32 | } 33 | 34 | if(rc == NGX_OK) 35 | { 36 | status = NGX_HTTP_OK; 37 | return; 38 | } 39 | 40 | if(rc < NGX_OK) 41 | { 42 | status = NGX_HTTP_INTERNAL_SERVER_ERROR; 43 | return; 44 | } 45 | 46 | status = rc; 47 | } 48 | }; 49 | 50 | //NGX_MOD_INSTANCE(NdgDataHookModule, ndg_data_hook_module) 51 | NGX_MOD_CTX_INSTANCE(NdgDataHookModule, ndg_data_hook_module, NdgDataHookCtx) 52 | 53 | #endif //_NDG_DATA_HOOK_CONF_HPP 54 | -------------------------------------------------------------------------------- /legacy/datahook/NdgDataHookHandler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_DATA_HOOK_HANDLER_HPP 4 | #define _NDG_DATA_HOOK_HANDLER_HPP 5 | 6 | #include "NdgDataHookConf.hpp" 7 | 8 | class NdgDataHookHandler final 9 | { 10 | public: 11 | typedef NdgDataHookHandler this_type; 12 | typedef NdgDataHookCtx ctx_type; 13 | 14 | typedef NdgDataHookModule this_module; 15 | typedef NgxFilter this_filter; 16 | public: 17 | static ngx_int_t init(ngx_conf_t* cf) 18 | { 19 | this_filter::init(&this_type::header_filter, &this_type::body_filter); 20 | return NGX_OK; 21 | } 22 | public: 23 | static ngx_int_t header_filter(ngx_http_request_t *r) 24 | try 25 | { 26 | auto pr = r->parent; 27 | if(!pr) //no parent request 28 | { 29 | return this_filter::next(r); 30 | } 31 | 32 | auto& ctx = this_module::ctx(); 33 | 34 | if(ctx.empty(pr)) // no parent ctx set 35 | { 36 | return this_filter::next(r); 37 | } 38 | 39 | auto& pr_ctx_data = this_module::data(pr); 40 | 41 | if(!pr_ctx_data.hook) // no parent hook flag 42 | { 43 | return this_filter::next(r); 44 | } 45 | 46 | this_module::data(r).do_hook = true; 47 | 48 | //pr_ctx_data.status = r->headers_out.status; 49 | pr_ctx_data.headers = &r->headers_out; // subrequest's headers 50 | 51 | r->filter_need_in_memory = true; 52 | r->header_sent = true; 53 | 54 | return NGX_OK; // stop header filter chain 55 | } 56 | catch(const NgxException& e) 57 | { 58 | return e.code(); 59 | } 60 | 61 | public: 62 | static ngx_int_t body_filter(ngx_http_request_t *r, ngx_chain_t *in) 63 | try 64 | { 65 | if(!in) 66 | { 67 | return NGX_OK; //this_filter::next(r, in); 68 | } 69 | 70 | if( this_module::ctx().empty(r) || 71 | !this_module::data(r).do_hook) 72 | { 73 | return this_filter::next(r, in); 74 | } 75 | 76 | // parent ctx data 77 | auto& pr_ctx_data = this_module::data(r->parent); 78 | 79 | // copy to parent ctx 80 | auto rc = ngx_chain_add_copy(r->pool, &pr_ctx_data.body, in); 81 | 82 | NgxException::require(rc); 83 | 84 | return NGX_OK; // stop body filter chain 85 | } 86 | catch(const NgxException& e) 87 | { 88 | return e.code(); 89 | } 90 | 91 | }; 92 | 93 | #endif //_NDG_DATA_HOOK_HANDLER_HPP 94 | -------------------------------------------------------------------------------- /legacy/datahook/NdgDataHookInit.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_DATA_HOOK_INIT_HPP 4 | #define _NDG_DATA_HOOK_INIT_HPP 5 | 6 | #include "NdgDataHookConf.hpp" 7 | #include "NdgDataHookHandler.hpp" 8 | 9 | class NdgDataHookInit final 10 | { 11 | public: 12 | typedef NdgDataHookHandler handler_type; 13 | typedef NdgDataHookInit this_type; 14 | public: 15 | static ngx_http_module_t* ctx() 16 | { 17 | static ngx_http_module_t c = 18 | { 19 | NGX_MODULE_NULL(1), 20 | &handler_type::init, 21 | NGX_MODULE_NULL(6), 22 | }; 23 | 24 | return &c; 25 | } 26 | public: 27 | static const ngx_module_t& module() 28 | { 29 | static ngx_module_t m = 30 | { 31 | NGX_MODULE_V1, 32 | 33 | ctx(), 34 | nullptr, 35 | 36 | NGX_HTTP_MODULE, 37 | NGX_MODULE_NULL(7), 38 | NGX_MODULE_V1_PADDING 39 | }; 40 | 41 | return m; 42 | } 43 | }; 44 | 45 | #endif //_NDG_DATA_HOOK_INIT_HPP 46 | -------------------------------------------------------------------------------- /legacy/datahook/config: -------------------------------------------------------------------------------- 1 | #./configure --add-module=$HOME/ngx_cpp_dev/modules/data_hook 2 | 3 | ngx_addon_name=ndg_data_hook_module 4 | 5 | if test -n "$ngx_module_link"; then 6 | ngx_module_type=HTTP_FILTER 7 | ngx_module_name=ndg_data_hook_module 8 | ngx_module_srcs="$ngx_addon_dir/ModNdgDataHook.cpp" 9 | 10 | . auto/module 11 | else 12 | HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES ndg_data_hook_module" 13 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ModNdgDataHook.cpp" 14 | fi 15 | -------------------------------------------------------------------------------- /legacy/echo/ModNdgEcho.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | 4 | #include "NdgEchoInit.hpp" 5 | 6 | auto ndg_echo_module = NdgEchoInit::module(); 7 | 8 | -------------------------------------------------------------------------------- /legacy/echo/NdgEchoConf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_ECHO_CONF_HPP 4 | #define _NDG_ECHO_CONF_HPP 5 | 6 | #include "NgxAll.hpp" 7 | 8 | #define ENABLE_SCRIPT 9 | 10 | class NdgEchoConf final 11 | { 12 | public: 13 | typedef NdgEchoConf this_type; 14 | public: 15 | NdgEchoConf() = default; 16 | ~NdgEchoConf() = default; 17 | public: 18 | ngx_str_t msg; 19 | #ifdef ENABLE_SCRIPT 20 | NgxComplexValue var; 21 | #endif 22 | public: 23 | static void* create(ngx_conf_t* cf) 24 | { 25 | return NgxPool(cf).alloc(); 26 | } 27 | 28 | static this_type& cast(void* conf) 29 | { 30 | return *reinterpret_cast(conf); 31 | } 32 | }; 33 | 34 | NGX_MOD_INSTANCE(NdgEchoModule, ndg_echo_module, NdgEchoConf) 35 | 36 | #endif //_NDG_ECHO_CONF_HPP 37 | -------------------------------------------------------------------------------- /legacy/echo/NdgEchoHandler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_ECHO_HANDLER_HPP 4 | #define _NDG_ECHO_HANDLER_HPP 5 | 6 | #include 7 | 8 | #include "NdgEchoConf.hpp" 9 | 10 | class NdgEchoHandler final 11 | { 12 | public: 13 | typedef NdgEchoHandler this_type; 14 | typedef NdgEchoModule this_module; 15 | public: 16 | static ngx_int_t handler(ngx_http_request_t *r) 17 | { 18 | //req_line(r); 19 | //req_headers(r); 20 | 21 | return process(r); 22 | } 23 | private: 24 | static ngx_int_t process(ngx_http_request_t *r) 25 | try 26 | { 27 | using namespace std; 28 | 29 | NgxRequest req(r); 30 | 31 | if(!req.method(NGX_HTTP_GET)) 32 | { 33 | return NGX_HTTP_NOT_ALLOWED; 34 | } 35 | 36 | req.body().discard(); 37 | 38 | auto& cf = this_module::conf().loc(r); 39 | #ifdef ENABLE_SCRIPT 40 | auto str = cf.var.str(r); 41 | NgxString msg = str; 42 | 43 | // warning. do not use like this 44 | //NgxString msg = cf.var.str(r); 45 | #else 46 | NgxString msg = cf.msg; 47 | #endif 48 | // check args 49 | NgxString args = req->args; 50 | 51 | auto len = msg.size(); 52 | if(!args.empty()) 53 | { 54 | len += args.size()+1; 55 | } 56 | 57 | NgxResponse resp(r); 58 | 59 | //auto h = resp.headers(); 60 | 61 | resp.length(len); 62 | resp.status(NGX_HTTP_OK); 63 | 64 | if(!args.empty()) 65 | { 66 | resp.send(args); 67 | resp.send(","); 68 | } 69 | 70 | resp.send(msg); 71 | resp.flush(); 72 | 73 | return resp.eof(); 74 | } 75 | catch(const NgxException& e) 76 | { 77 | return e.code(); 78 | } 79 | 80 | static void req_line(ngx_http_request_t *r) 81 | { 82 | using namespace std; 83 | 84 | cout << r->request_line<< endl; 85 | cout << r->method_name << endl; 86 | cout << r->http_protocol<< endl; 87 | cout << r->uri<< endl; 88 | cout << r->args<< endl; 89 | cout << r->exten<< endl; 90 | cout << r->unparsed_uri<< endl; 91 | 92 | //NgxBuf b(r->header_in); 93 | //cout << b.boundary().len << endl; 94 | NgxVarManager var(r); 95 | cout << "var:"; 96 | //cout << var.get("request_method")<< endl; 97 | cout << var["request_method"]<< endl; 98 | cout << var["var1"]<< endl; 99 | assert(!var["abc"].get().len); 100 | 101 | //var.set("var1", "1234567"); 102 | var["var1"] = "1234567"; 103 | cout << var["var1"]<< endl; 104 | } 105 | 106 | static void req_headers(ngx_http_request_t *r) 107 | { 108 | using namespace std; 109 | 110 | NgxRequest req(r); 111 | 112 | auto hi = req.headers(); 113 | 114 | cout << "host = "<"<< kv.value 120 | << ":"<args); 68 | auto& lcf = conf_type::cast(conf); 69 | 70 | lcf.var.init(cf, args[1]); 71 | #else 72 | auto rc = ngx_conf_set_str_slot(cf, cmd, conf); 73 | 74 | if(rc != NGX_CONF_OK) 75 | { 76 | return rc; 77 | } 78 | #endif 79 | 80 | NgxHttpCoreModule::handler( 81 | cf, &handler_type::handler); 82 | 83 | return NGX_CONF_OK; 84 | } 85 | }; 86 | 87 | #endif //_NDG_ECHO_INIT_HPP 88 | -------------------------------------------------------------------------------- /legacy/echo/config: -------------------------------------------------------------------------------- 1 | #./configure --add-module=$HOME/ngx_cpp_dev/modules/echo 2 | 3 | ngx_addon_name=ndg_echo_module 4 | 5 | 6 | if test -n "$ngx_module_link"; then 7 | ngx_module_type=HTTP 8 | ngx_module_name=ndg_echo_module 9 | ngx_module_srcs="$ngx_addon_dir/ModNdgEcho.cpp" 10 | 11 | . auto/module 12 | else 13 | HTTP_MODULES="$HTTP_MODULES ndg_echo_module" 14 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ModNdgEcho.cpp" 15 | fi 16 | 17 | -------------------------------------------------------------------------------- /legacy/footer/ModNdgFooter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 2 | // Author: Chrono Law 3 | 4 | #include "NdgFooterInit.hpp" 5 | 6 | auto ndg_footer_module = NdgFooterInit::module(); 7 | 8 | -------------------------------------------------------------------------------- /legacy/footer/NdgFooterConf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_FOOTER_CONF_HPP 4 | #define _NDG_FOOTER_CONF_HPP 5 | 6 | #include "NgxAll.hpp" 7 | 8 | class NdgFooterConf final 9 | { 10 | public: 11 | typedef NdgFooterConf this_type; 12 | public: 13 | NdgFooterConf() = default; 14 | ~NdgFooterConf() = default; 15 | public: 16 | ngx_array_t* headers; 17 | ngx_str_t footer; 18 | public: 19 | static void* create(ngx_conf_t* cf) 20 | { 21 | return NgxPool(cf).alloc(); 22 | } 23 | 24 | }; 25 | 26 | struct NdgFooterCtx final 27 | { 28 | int flag = 0; 29 | }; 30 | 31 | NGX_MOD_CTX_INSTANCE(NdgFooterModule, ndg_footer_module, NdgFooterCtx, NdgFooterConf) 32 | 33 | #endif //_NDG_FOOTER_CONF_HPP 34 | -------------------------------------------------------------------------------- /legacy/footer/NdgFooterHandler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_FOOTER_HANDLER_HPP 4 | #define _NDG_FOOTER_HANDLER_HPP 5 | 6 | #include "NdgFooterConf.hpp" 7 | 8 | class NdgFooterHandler final 9 | { 10 | public: 11 | typedef NdgFooterHandler this_type; 12 | typedef NdgFooterModule this_module; 13 | typedef NgxFilter this_filter; 14 | public: 15 | static ngx_int_t init(ngx_conf_t* cf) 16 | { 17 | this_filter::init(&this_type::header_filter, &this_type::body_filter); 18 | return NGX_OK; 19 | } 20 | public: 21 | static ngx_int_t header_filter(ngx_http_request_t *r) 22 | try 23 | { 24 | do_header_filter(r); 25 | return this_filter::next(r); 26 | } 27 | catch(const NgxException& e) 28 | { 29 | return e.code(); 30 | } 31 | 32 | static void do_header_filter(ngx_http_request_t *r) 33 | { 34 | auto& ctx = this_module::data(r); 35 | if(ctx.flag) 36 | { 37 | return; 38 | } 39 | 40 | ctx.flag = 1; 41 | NgxResponse resp(r); 42 | 43 | auto& cf = this_module::conf().loc(r); 44 | 45 | NgxKvArray headers = cf.headers; 46 | 47 | for(auto i = 0u; i < headers.size();++i) 48 | { 49 | auto& header = headers[i]; 50 | 51 | ngx_table_elt_t kv; 52 | 53 | kv.hash = 1; 54 | kv.key = header.key; 55 | kv.value = header.value; 56 | 57 | resp.headers().add(kv); 58 | } 59 | 60 | // check r->header_only r->method & NGX_HTTP_HEAD 61 | NgxString footer = cf.footer; 62 | if(footer.empty()) 63 | { 64 | return; 65 | } 66 | 67 | auto len = resp.headers()->content_length_n; 68 | if(len > 0) 69 | { 70 | resp.length(len + footer.size()); 71 | } 72 | } 73 | 74 | public: 75 | static ngx_int_t body_filter(ngx_http_request_t *r, ngx_chain_t *in) 76 | try 77 | { 78 | do_body_filter(r, in); 79 | return this_filter::next(r, in); 80 | } 81 | catch(const NgxException& e) 82 | { 83 | return e.code(); 84 | } 85 | 86 | static void do_body_filter(ngx_http_request_t *r, ngx_chain_t *in) 87 | { 88 | auto& cf = this_module::conf().loc(r); 89 | 90 | NgxString footer = cf.footer; 91 | if(footer.empty()) 92 | { 93 | return; 94 | } 95 | 96 | auto& ctx = this_module::data(r); 97 | if(ctx.flag != 1) 98 | { 99 | return; 100 | } 101 | 102 | NgxChain ch = in; 103 | auto p = ch.begin(); 104 | for(; p != ch.end();++p) 105 | { 106 | if(p->data().last()) 107 | { 108 | break; 109 | } 110 | } 111 | 112 | if(p == ch.end()) 113 | { 114 | return; 115 | } 116 | 117 | ctx.flag = 2; 118 | 119 | NgxPool pool(r); 120 | 121 | NgxBuf buf = pool.buffer(); 122 | buf.range(footer); 123 | buf.finish(); 124 | 125 | if(!p->data().size()) 126 | { 127 | p->set(buf); 128 | return; 129 | } 130 | 131 | NgxChainNode n = pool.chain(); 132 | n.set(buf); 133 | n.finish(); 134 | 135 | p->link(n); 136 | p->data().finish(false); 137 | } 138 | }; 139 | 140 | #endif //_NDG_FOOTER_HANDLER_HPP 141 | -------------------------------------------------------------------------------- /legacy/footer/NdgFooterInit.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_FOOTER_INIT_HPP 4 | #define _NDG_FOOTER_INIT_HPP 5 | 6 | #include "NdgFooterConf.hpp" 7 | #include "NdgFooterHandler.hpp" 8 | 9 | class NdgFooterInit final 10 | { 11 | public: 12 | typedef NdgFooterConf conf_type; 13 | typedef NdgFooterHandler handler_type; 14 | typedef NdgFooterInit this_type; 15 | public: 16 | static ngx_command_t* cmds() 17 | { 18 | static ngx_command_t n[] = 19 | { 20 | { 21 | ngx_string("ndg_header"), 22 | NgxTake(NGX_HTTP_LOC_CONF, 2), 23 | ngx_conf_set_keyval_slot, 24 | NGX_HTTP_LOC_CONF_OFFSET, 25 | offsetof(conf_type, headers), 26 | nullptr 27 | }, 28 | 29 | { 30 | ngx_string("ndg_footer"), 31 | NgxTake(NGX_HTTP_LOC_CONF, 1), 32 | ngx_conf_set_str_slot, 33 | NGX_HTTP_LOC_CONF_OFFSET, 34 | offsetof(conf_type, footer), 35 | nullptr 36 | }, 37 | 38 | ngx_null_command 39 | }; 40 | 41 | return n; 42 | } 43 | public: 44 | static ngx_http_module_t* ctx() 45 | { 46 | static ngx_http_module_t c = 47 | { 48 | NGX_MODULE_NULL(1), 49 | &handler_type::init, 50 | NGX_MODULE_NULL(4), 51 | &conf_type::create, 52 | NGX_MODULE_NULL(1), 53 | }; 54 | 55 | return &c; 56 | } 57 | public: 58 | static const ngx_module_t& module() 59 | { 60 | static ngx_module_t m = 61 | { 62 | NGX_MODULE_V1, 63 | 64 | ctx(), 65 | cmds(), 66 | 67 | NGX_HTTP_MODULE, 68 | NGX_MODULE_NULL(7), 69 | NGX_MODULE_V1_PADDING 70 | }; 71 | 72 | return m; 73 | } 74 | }; 75 | 76 | #endif //_NDG_FOOTER_INIT_HPP 77 | -------------------------------------------------------------------------------- /legacy/footer/config: -------------------------------------------------------------------------------- 1 | #./configure --add-module=$HOME/ngx_cpp_dev/modules/footer 2 | 3 | ngx_addon_name=ndg_footer_module 4 | 5 | if test -n "$ngx_module_link"; then 6 | ngx_module_type=HTTP_FILTER 7 | ngx_module_name=ndg_footer_module 8 | ngx_module_srcs="$ngx_addon_dir/ModNdgFooter.cpp" 9 | 10 | . auto/module 11 | else 12 | HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES ndg_footer_module" 13 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ModNdgFooter.cpp" 14 | fi 15 | -------------------------------------------------------------------------------- /legacy/loadbalance/ModNdgLoadBalance.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 2 | // Author: Chrono Law 3 | 4 | #include "NdgLoadBalanceInit.hpp" 5 | 6 | auto ndg_load_balance_module = NdgLoadBalanceInit::module(); 7 | 8 | -------------------------------------------------------------------------------- /legacy/loadbalance/NdgLoadBalanceConf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_LOAD_BALANCE_CONF_HPP 4 | #define _NDG_LOAD_BALANCE_CONF_HPP 5 | 6 | #include "NgxAll.hpp" 7 | 8 | //NGX_MOD_INSTANCE(NdgLoadBalanceModule, ndg_load_balance_module) 9 | 10 | #endif //_NDG_LOAD_BALANCE_CONF_HPP 11 | -------------------------------------------------------------------------------- /legacy/loadbalance/NdgLoadBalanceHandler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_LOAD_BALANCE_HANDLER_HPP 4 | #define _NDG_LOAD_BALANCE_HANDLER_HPP 5 | 6 | #include 7 | 8 | #include "NdgLoadBalanceConf.hpp" 9 | 10 | class NdgLoadBalanceCallback final 11 | { 12 | public: 13 | typedef NgxLogDebug log; 14 | typedef NdgLoadBalanceCallback this_type; 15 | typedef boost::rand48 random_type; 16 | public: 17 | // the round robin data must be first 18 | ngx_http_upstream_rr_peer_data_t rrp; 19 | 20 | u_char tries = 0; 21 | ngx_event_get_peer_pt get_rr_peer = ngx_http_upstream_get_round_robin_peer; 22 | public: 23 | static ngx_int_t get(ngx_peer_connection_t *pc, void *data) 24 | { 25 | auto& peer_data = *reinterpret_cast(data); 26 | auto& peers = *peer_data.rrp.peers; 27 | 28 | if(peer_data.tries++ > 5 || peers.single) 29 | { 30 | return peer_data.get_rr_peer(pc, &peer_data.rrp); 31 | } 32 | 33 | static random_type rand(time(0)); 34 | 35 | auto& peer = peers.peer[rand() % peers.number]; 36 | 37 | pc->sockaddr = peer.sockaddr; 38 | pc->socklen = peer.socklen; 39 | pc->name = &peer.name; 40 | 41 | log(pc->log).print("peer=%V", &peer.name); 42 | 43 | pc->cached = false; 44 | pc->connection = nullptr; 45 | 46 | return NGX_OK; 47 | } 48 | 49 | public: 50 | static void free(ngx_peer_connection_t *pc, void *data, ngx_uint_t state) 51 | { 52 | //auto peer_data = reinterpret_cast(data); 53 | } 54 | }; 55 | 56 | class NdgLoadBalanceHandler final 57 | { 58 | public: 59 | typedef NdgLoadBalanceHandler this_type; 60 | typedef NdgLoadBalanceCallback callback_type; 61 | typedef NdgLoadBalanceCallback peer_data_type; 62 | 63 | //typedef NdgLoadBalanceModule this_module; 64 | typedef NgxLoadBalance 66 | //&callback_type::free> 67 | this_load_balance; 68 | public: 69 | static ngx_int_t init(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) 70 | try 71 | { 72 | this_load_balance::init(cf, us, &this_type::init_peer); 73 | return NGX_OK; 74 | } 75 | catch(const NgxException& e) 76 | { 77 | return e.code(); 78 | } 79 | public: 80 | static ngx_int_t init_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) 81 | { 82 | this_load_balance::init(r, us); 83 | 84 | return NGX_OK; 85 | } 86 | }; 87 | 88 | #endif //_NDG_LOAD_BALANCE_HANDLER_HPP 89 | -------------------------------------------------------------------------------- /legacy/loadbalance/NdgLoadBalanceInit.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_LOAD_BALANCE_INIT_HPP 4 | #define _NDG_LOAD_BALANCE_INIT_HPP 5 | 6 | #include "NdgLoadBalanceConf.hpp" 7 | #include "NdgLoadBalanceHandler.hpp" 8 | 9 | class NdgLoadBalanceInit final 10 | { 11 | public: 12 | typedef NdgLoadBalanceHandler handler_type; 13 | typedef NdgLoadBalanceInit this_type; 14 | public: 15 | static ngx_command_t* cmds() 16 | { 17 | static ngx_command_t n[] = 18 | { 19 | { 20 | ngx_string("ndg_load_balance"), 21 | NgxTake(NGX_HTTP_UPS_CONF, 0), 22 | &this_type::set_load_balance, 23 | 0,0,nullptr 24 | }, 25 | 26 | ngx_null_command 27 | }; 28 | 29 | return n; 30 | } 31 | public: 32 | static ngx_http_module_t* ctx() 33 | { 34 | static ngx_http_module_t c = 35 | { 36 | NGX_MODULE_NULL(8) 37 | }; 38 | 39 | return &c; 40 | } 41 | public: 42 | static const ngx_module_t& module() 43 | { 44 | static ngx_module_t m = 45 | { 46 | NGX_MODULE_V1, 47 | 48 | ctx(), 49 | cmds(), 50 | 51 | NGX_HTTP_MODULE, 52 | NGX_MODULE_NULL(7), 53 | NGX_MODULE_V1_PADDING 54 | }; 55 | 56 | return m; 57 | } 58 | private: 59 | static char* set_load_balance(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) 60 | { 61 | NgxHttpUpstreamModule::init(cf, &handler_type::init); 62 | 63 | return NGX_CONF_OK; 64 | } 65 | }; 66 | 67 | #endif //_NDG_LOAD_BALANCE_INIT_HPP 68 | -------------------------------------------------------------------------------- /legacy/loadbalance/config: -------------------------------------------------------------------------------- 1 | #./configure --add-module=$HOME/ngx_cpp_dev/modules/loadbalance 2 | 3 | ngx_addon_name=ndg_load_balance_module 4 | 5 | if test -n "$ngx_module_link"; then 6 | ngx_module_type=HTTP 7 | ngx_module_name=ndg_load_balance_module 8 | ngx_module_srcs="$ngx_addon_dir/ModNdgLoadBalance.cpp" 9 | 10 | . auto/module 11 | else 12 | HTTP_MODULES="$HTTP_MODULES ndg_load_balance_module" 13 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ModNdgLoadBalance.cpp" 14 | fi 15 | -------------------------------------------------------------------------------- /legacy/shmem/ModNdgShmem.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 2 | // Author: Chrono Law 3 | #include "NdgShmemInit.hpp" 4 | 5 | auto ndg_shmem_module = NdgShmemInit::module(); 6 | 7 | 8 | -------------------------------------------------------------------------------- /legacy/shmem/NdgShmemConf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_SHMEM_CONF_HPP 4 | #define _NDG_SHMEM_CONF_HPP 5 | 6 | #include "NgxAll.hpp" 7 | 8 | class NdgShmemConf final 9 | { 10 | public: 11 | typedef NdgShmemConf this_type; 12 | public: 13 | NdgShmemConf() = default; 14 | ~NdgShmemConf() = default; 15 | public: 16 | std::size_t size = NgxUnsetValue::get(); 17 | public: 18 | static void* create(ngx_conf_t* cf) 19 | { 20 | return NgxPool(cf).alloc(); 21 | } 22 | 23 | static char* init(ngx_conf_t *cf, void *c) 24 | { 25 | boost::ignore_unused(cf); 26 | 27 | auto conf = reinterpret_cast(c); 28 | 29 | NgxValue::init(conf->size, 1024); 30 | 31 | return NGX_CONF_OK; 32 | } 33 | }; 34 | 35 | NGX_MOD_INSTANCE(NdgShmemModule, ndg_shmem_module, void, void, NdgShmemConf) 36 | 37 | #endif //_NDG_SHMEM_CONF_HPP 38 | -------------------------------------------------------------------------------- /legacy/shmem/NdgShmemHandler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_SHMEM_HANDLER_HPP 4 | #define _NDG_SHMEM_HANDLER_HPP 5 | 6 | #include 7 | #include 8 | 9 | #include "NdgShmemConf.hpp" 10 | 11 | class NdgShmemHandler final 12 | { 13 | public: 14 | typedef NdgShmemHandler this_type; 15 | typedef NdgShmemModule this_module; 16 | typedef NgxLogDebug log; 17 | 18 | typedef boost::interprocess::managed_shared_memory shmem_type; 19 | typedef boost::atomic atomic_type; 20 | public: 21 | static ngx_int_t init(ngx_conf_t* cf) 22 | { 23 | NgxHttpCoreModule::handler( 24 | cf, &this_type::handler, NGX_HTTP_LOG_PHASE); 25 | 26 | return NGX_OK; 27 | } 28 | 29 | public: 30 | static void exit_master(ngx_cycle_t *cycle) 31 | { 32 | boost::interprocess::shared_memory_object::remove("ndg_shmem"); 33 | } 34 | public: 35 | static ngx_int_t handler(ngx_http_request_t *r) 36 | try 37 | { 38 | static auto& cf = this_module::conf().main(r); 39 | 40 | static shmem_type segment( 41 | boost::interprocess::open_or_create, "ndg_shmem", 42 | cf.size); 43 | 44 | auto& counter = *segment.find_or_construct("counter")(0); 45 | 46 | counter += r->connection->sent; 47 | 48 | log(r).print("sent=%l", static_cast(counter)); 49 | 50 | return NGX_OK; 51 | } 52 | catch(const NgxException& e) 53 | { 54 | return e.code(); 55 | } 56 | }; 57 | 58 | #endif //_NDG_SHMEM_HANDLER_HPP 59 | -------------------------------------------------------------------------------- /legacy/shmem/NdgShmemInit.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_SHMEM_INIT_HPP 4 | #define _NDG_SHMEM_INIT_HPP 5 | 6 | #include "NdgShmemConf.hpp" 7 | #include "NdgShmemHandler.hpp" 8 | 9 | class NdgShmemInit final 10 | { 11 | public: 12 | typedef NdgShmemConf conf_type; 13 | typedef NdgShmemHandler handler_type; 14 | typedef NdgShmemInit this_type; 15 | public: 16 | static ngx_command_t* cmds() 17 | { 18 | static ngx_command_t n[] = 19 | { 20 | { 21 | ngx_string("ndg_shmem_size"), 22 | NgxTake(NGX_HTTP_MAIN_CONF, 1), 23 | ngx_conf_set_size_slot, 24 | NGX_HTTP_MAIN_CONF_OFFSET, 25 | offsetof(conf_type, size), 26 | nullptr 27 | }, 28 | 29 | ngx_null_command 30 | }; 31 | 32 | return n; 33 | } 34 | public: 35 | static ngx_http_module_t* ctx() 36 | { 37 | static ngx_http_module_t c = 38 | { 39 | NGX_MODULE_NULL(1), 40 | 41 | &handler_type::init, 42 | 43 | &conf_type::create, 44 | &conf_type::init, 45 | 46 | NGX_MODULE_NULL(4), 47 | }; 48 | 49 | return &c; 50 | } 51 | public: 52 | static const ngx_module_t& module() 53 | { 54 | static ngx_module_t m = 55 | { 56 | NGX_MODULE_V1, 57 | 58 | ctx(), 59 | cmds(), 60 | 61 | NGX_HTTP_MODULE, 62 | NGX_MODULE_NULL(6), 63 | 64 | &handler_type::exit_master, 65 | 66 | NGX_MODULE_V1_PADDING 67 | }; 68 | 69 | return m; 70 | } 71 | private: 72 | }; 73 | 74 | #endif //_NDG_SHMEM_INIT_HPP 75 | 76 | -------------------------------------------------------------------------------- /legacy/shmem/config: -------------------------------------------------------------------------------- 1 | #./configure --add-module=$HOME/ngx_cpp_dev/modules/shmem 2 | 3 | ngx_addon_name=ndg_shmem_module 4 | 5 | if test -n "$ngx_module_link"; then 6 | ngx_module_type=HTTP 7 | ngx_module_name=ndg_shmem_module 8 | ngx_module_srcs="$ngx_addon_dir/ModNdgShmem.cpp" 9 | ngx_module_libs="-lrt" 10 | 11 | . auto/module 12 | else 13 | HTTP_MODULES="$HTTP_MODULES ndg_shmem_module" 14 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ModNdgShmem.cpp" 15 | CORE_LIBS="$CORE_LIBS -lrt" 16 | fi 17 | 18 | -------------------------------------------------------------------------------- /legacy/subrequest/ModNdgSubrequest.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 2 | // Author: Chrono Law 3 | 4 | #include "NdgSubrequestInit.hpp" 5 | 6 | auto ndg_subrequest_module = NdgSubrequestInit::module(); 7 | 8 | -------------------------------------------------------------------------------- /legacy/subrequest/NdgSubrequestConf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_SUBREQUEST_CONF_HPP 4 | #define _NDG_SUBREQUEST_CONF_HPP 5 | 6 | #include "NgxAll.hpp" 7 | 8 | class NdgSubrequestConf final 9 | { 10 | public: 11 | typedef NdgSubrequestConf this_type; 12 | public: 13 | NdgSubrequestConf() = default; 14 | ~NdgSubrequestConf() = default; 15 | public: 16 | ngx_str_t loc; 17 | ngx_str_t args; 18 | public: 19 | static void* create(ngx_conf_t* cf) 20 | { 21 | return NgxPool(cf).alloc(); 22 | } 23 | 24 | static char* merge(ngx_conf_t *cf, void *parent, void *child) 25 | { 26 | boost::ignore_unused(cf); 27 | 28 | auto prev = reinterpret_cast(parent); 29 | auto conf = reinterpret_cast(child); 30 | 31 | NgxValue::merge(conf->loc, prev->loc, ngx_str_t ngx_string("/echo")); 32 | NgxValue::merge(conf->args, prev->args, ngx_str_t ngx_null_string); 33 | 34 | return NGX_CONF_OK; 35 | } 36 | }; 37 | 38 | NGX_MOD_INSTANCE(NdgSubrequestModule, ndg_subrequest_module, NdgSubrequestConf) 39 | 40 | #endif //_NDG_SUBREQUEST_CONF_HPP 41 | -------------------------------------------------------------------------------- /legacy/subrequest/NdgSubrequestHandler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_SUBREQUEST_HANDLER_HPP 4 | #define _NDG_SUBREQUEST_HANDLER_HPP 5 | 6 | //#include 7 | //using namespace std; 8 | 9 | #include "NdgSubrequestConf.hpp" 10 | //#include "../datahook/NdgDataHookConf.hpp" 11 | 12 | #if nginx_version < 1013010 13 | #error "need latest nginx!" 14 | #endif 15 | 16 | class NdgSubrequestCallback final 17 | { 18 | public: 19 | typedef NgxLogDebug log; 20 | //typedef NdgDataHookModule hook_module; 21 | public: 22 | static ngx_int_t sub_post(ngx_http_request_t* r, void* data, ngx_int_t rc) 23 | { 24 | // r is subrequest 25 | //auto& pr_ctx_data = hook_module::data(r->parent); 26 | //pr_ctx_data.state(rc); 27 | 28 | return NGX_OK; 29 | } 30 | 31 | static ngx_int_t parent_post(ngx_http_request_t* r) 32 | { 33 | // r is parent request 34 | //auto& ctx_data = hook_module::data(r); 35 | 36 | //if(ctx_data.status != NGX_HTTP_OK) 37 | //{ 38 | // return NGX_HTTP_INTERNAL_SERVER_ERROR; 39 | //} 40 | 41 | //NgxHeadersOut h(ctx_data.headers); 42 | //NgxHeadersChecker()(h); 43 | 44 | auto sr = r->postponed->request; 45 | NgxHeadersOut h(sr); 46 | 47 | if(h->status != NGX_HTTP_OK) 48 | { 49 | return NGX_HTTP_INTERNAL_SERVER_ERROR; 50 | } 51 | 52 | ngx_str_t msg = ngx_string("subrequest"); 53 | 54 | //NgxChain chain = ctx_data.body; 55 | NgxChainNode ch = sr->out; 56 | auto len = msg.len + ch.data().size(); 57 | 58 | NgxResponse resp(r); 59 | 60 | resp.length(len); 61 | 62 | h.list().visit( 63 | [&](ngx_table_elt_t& x) 64 | { 65 | resp.headers().add(x); 66 | }); 67 | 68 | assert(ch.data().last()); 69 | ch.data().finish(false); 70 | resp.send(ch); 71 | //for(auto& ch : chain) 72 | //{ 73 | // if(ch.data().special()) 74 | // { 75 | // continue; 76 | // } 77 | 78 | // if(ch.data().last()) 79 | // { 80 | // ch.data().finish(false); 81 | // } 82 | 83 | // resp.send(ch.data()); 84 | //} 85 | 86 | resp.send(&msg); 87 | resp.eof(); 88 | 89 | return NGX_OK; 90 | } 91 | }; 92 | 93 | class NdgSubrequestHandler final 94 | { 95 | public: 96 | typedef NdgSubrequestHandler this_type; 97 | typedef NdgSubrequestCallback callback_type; 98 | //typedef NdgDataHookModule hook_module; 99 | 100 | typedef NdgSubrequestModule this_module; 101 | typedef NgxSubRequest this_subrequest; 102 | public: 103 | static ngx_int_t handler(ngx_http_request_t *r) 104 | try 105 | { 106 | NgxRequest req(r); 107 | if(!req.method(NGX_HTTP_GET)) 108 | { 109 | return NGX_HTTP_NOT_ALLOWED; 110 | } 111 | 112 | // get config 113 | auto& cf = this_module::conf().loc(r); 114 | 115 | this_subrequest(r).create(cf.loc, cf.args); 116 | 117 | //hook_module::data(r).hooking(); 118 | 119 | return NGX_DONE; 120 | } 121 | catch(const NgxException& e) 122 | { 123 | return e.code(); 124 | } 125 | }; 126 | 127 | #endif //_NDG_SUBREQUEST_HANDLER_HPP 128 | -------------------------------------------------------------------------------- /legacy/subrequest/NdgSubrequestInit.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_SUBREQUEST_INIT_HPP 4 | #define _NDG_SUBREQUEST_INIT_HPP 5 | 6 | #include "NdgSubrequestConf.hpp" 7 | #include "NdgSubrequestHandler.hpp" 8 | 9 | class NdgSubrequestInit final 10 | { 11 | public: 12 | typedef NdgSubrequestConf conf_type; 13 | typedef NdgSubrequestHandler handler_type; 14 | typedef NdgSubrequestInit this_type; 15 | public: 16 | static ngx_command_t* cmds() 17 | { 18 | static ngx_command_t n[] = 19 | { 20 | { 21 | ngx_string("ndg_subrequest_loc"), 22 | NgxTake(NGX_HTTP_LOC_CONF, 1), 23 | &this_type::set_subrequest_loc, 24 | NGX_HTTP_LOC_CONF_OFFSET, 25 | offsetof(conf_type, loc), 26 | nullptr 27 | }, 28 | 29 | { 30 | ngx_string("ndg_subrequest_args"), 31 | NgxTake(NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF, 1), 32 | ngx_conf_set_str_slot, 33 | NGX_HTTP_LOC_CONF_OFFSET, 34 | offsetof(conf_type, args), 35 | nullptr 36 | }, 37 | 38 | ngx_null_command 39 | }; 40 | 41 | return n; 42 | } 43 | public: 44 | static ngx_http_module_t* ctx() 45 | { 46 | static ngx_http_module_t c = 47 | { 48 | NGX_MODULE_NULL(6), 49 | &conf_type::create, 50 | &conf_type::merge 51 | }; 52 | 53 | return &c; 54 | } 55 | public: 56 | static const ngx_module_t& module() 57 | { 58 | static ngx_module_t m = 59 | { 60 | NGX_MODULE_V1, 61 | 62 | ctx(), 63 | cmds(), 64 | 65 | NGX_HTTP_MODULE, 66 | NGX_MODULE_NULL(7), 67 | NGX_MODULE_V1_PADDING 68 | }; 69 | 70 | return m; 71 | } 72 | private: 73 | static char* set_subrequest_loc(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) 74 | { 75 | ngx_conf_set_str_slot(cf, cmd, conf); 76 | 77 | NgxHttpCoreModule::handler( 78 | cf, &handler_type::handler); 79 | 80 | return NGX_CONF_OK; 81 | } 82 | }; 83 | 84 | #endif //_NDG_SUBREQUEST_INIT_HPP 85 | -------------------------------------------------------------------------------- /legacy/subrequest/config: -------------------------------------------------------------------------------- 1 | #./configure --add-module=$HOME/ngx_cpp_dev/modules/test 2 | 3 | ngx_addon_name=ndg_subrequest_module 4 | 5 | if test -n "$ngx_module_link"; then 6 | ngx_module_type=HTTP 7 | ngx_module_name=ndg_subrequest_module 8 | ngx_module_srcs="$ngx_addon_dir/ModNdgSubrequest.cpp" 9 | 10 | . auto/module 11 | else 12 | HTTP_MODULES="$HTTP_MODULES ndg_subrequest_module" 13 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ModNdgSubrequest.cpp" 14 | fi 15 | -------------------------------------------------------------------------------- /legacy/upstream/ModNdgUpstream.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 2 | // Author: Chrono Law 3 | 4 | #include "NdgUpstreamInit.hpp" 5 | 6 | auto ndg_upstream_module = NdgUpstreamInit::module(); 7 | 8 | -------------------------------------------------------------------------------- /legacy/upstream/NdgUpstreamConf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_UPSTREAM_CONF_HPP 4 | #define _NDG_UPSTREAM_CONF_HPP 5 | 6 | #include "NgxAll.hpp" 7 | 8 | class NdgUpstreamConf final 9 | { 10 | public: 11 | typedef NdgUpstreamConf this_type; 12 | public: 13 | NdgUpstreamConf() = default; 14 | ~NdgUpstreamConf() = default; 15 | public: 16 | ngx_http_upstream_conf_t upstream; 17 | public: 18 | static void* create(ngx_conf_t* cf) 19 | { 20 | auto& c = *NgxPool(cf).alloc(); 21 | 22 | c.upstream.connect_timeout = 1000*30; 23 | c.upstream.send_timeout = 1000*30; 24 | c.upstream.read_timeout = 1000*30; 25 | c.upstream.buffer_size = ngx_pagesize; 26 | 27 | return &c; 28 | } 29 | 30 | }; 31 | 32 | NGX_MOD_INSTANCE(NdgUpstreamModule, ndg_upstream_module, NdgUpstreamConf) 33 | 34 | #endif //_NDG_UPSTREAM_CONF_HPP 35 | -------------------------------------------------------------------------------- /legacy/upstream/NdgUpstreamHandler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_UPSTREAM_HANDLER_HPP 4 | #define _NDG_UPSTREAM_HANDLER_HPP 5 | 6 | #include "NdgUpstreamConf.hpp" 7 | 8 | class NdgUpstreamCallback final 9 | { 10 | public: 11 | typedef NgxUpstream upstream_type; 12 | typedef NgxLogDebug log; 13 | public: 14 | static ngx_int_t create_request(ngx_http_request_t* r) 15 | { 16 | ngx_str_t msg = ngx_string("xxxx"); 17 | 18 | if(r->args.len >= 4) 19 | { 20 | msg = r->args; 21 | msg.len = 4; 22 | } 23 | 24 | NgxPool pool(r); 25 | NgxUpstream u(r); 26 | 27 | NgxBuf buf = pool.buffer(); 28 | buf.range(msg); 29 | 30 | NgxChainNode ch = pool.chain(); 31 | ch.set(buf); 32 | 33 | log(r).print("proxy %V", msg); 34 | u.request(ch); 35 | 36 | log(r).print("send:%V", &r->args); 37 | 38 | return NGX_OK; 39 | } 40 | 41 | static ngx_int_t reinit_request(ngx_http_request_t* r) 42 | { 43 | return NGX_OK; 44 | } 45 | 46 | static ngx_int_t process_header(ngx_http_request_t* r) 47 | { 48 | NgxUpstream u(r); 49 | NgxBuf buf = u.buffer(); 50 | 51 | if(buf.size() < 2) 52 | { 53 | return NGX_AGAIN; 54 | } 55 | 56 | auto p = buf->pos; 57 | 58 | u.headers().content_length_n = (p[0] << 8) + p[1]; 59 | 60 | u.headers().status_n = NGX_HTTP_OK; 61 | 62 | u.state().status = NGX_HTTP_OK; 63 | 64 | buf.consume(2); 65 | 66 | return NGX_OK; 67 | } 68 | 69 | // input_filter 70 | }; 71 | 72 | class NdgUpstreamHandler final 73 | { 74 | public: 75 | typedef NdgUpstreamHandler this_type; 76 | typedef NdgUpstreamCallback callback_type; 77 | 78 | typedef NdgUpstreamModule this_module; 79 | typedef NgxUpstreamHelper< 80 | &callback_type::create_request, 81 | &callback_type::reinit_request, 82 | &callback_type::process_header> 83 | this_upstream; 84 | public: 85 | static ngx_int_t handler(ngx_http_request_t *r) 86 | try 87 | { 88 | NgxRequest req(r); 89 | if(!req.method(NGX_HTTP_GET)) 90 | { 91 | return NGX_HTTP_NOT_ALLOWED; 92 | } 93 | 94 | this_upstream u(r); 95 | 96 | // get config 97 | auto& cf = this_module::conf().loc(r); 98 | 99 | // set upstream confg 100 | u.conf(cf.upstream); 101 | //u.buffering(cf.upstream.buffering); 102 | 103 | //u->resolved = NgxPool(r).alloc(); 104 | //u->resolved->sockaddr = local_addr(); 105 | //u->resolved->socklen = sizeof(sockaddr_in); 106 | //u->resolved->naddrs = 1; 107 | 108 | return u.start(); 109 | } 110 | catch(const NgxException& e) 111 | { 112 | return e.code(); 113 | } 114 | 115 | static sockaddr* local_addr() 116 | { 117 | static sockaddr_in addr; 118 | 119 | addr.sin_family = AF_INET; 120 | addr.sin_port = htons(80); 121 | addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 122 | 123 | return (sockaddr*)&addr; 124 | } 125 | }; 126 | 127 | #endif //_NDG_UPSTREAM_HANDLER_HPP 128 | -------------------------------------------------------------------------------- /legacy/upstream/NdgUpstreamInit.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_UPSTREAM_INIT_HPP 4 | #define _NDG_UPSTREAM_INIT_HPP 5 | 6 | #include "NdgUpstreamConf.hpp" 7 | #include "NdgUpstreamHandler.hpp" 8 | 9 | class NdgUpstreamInit final 10 | { 11 | public: 12 | typedef NdgUpstreamConf conf_type; 13 | typedef NdgUpstreamHandler handler_type; 14 | typedef NdgUpstreamInit this_type; 15 | public: 16 | static ngx_command_t* cmds() 17 | { 18 | static ngx_command_t n[] = 19 | { 20 | { 21 | ngx_string("ndg_upstream_pass"), 22 | NgxTake(NGX_HTTP_LOC_CONF, 1), 23 | &this_type::set_upstream_pass, 24 | NGX_HTTP_LOC_CONF_OFFSET, 25 | 0, nullptr 26 | }, 27 | 28 | ngx_null_command 29 | }; 30 | 31 | return n; 32 | } 33 | public: 34 | static ngx_http_module_t* ctx() 35 | { 36 | static ngx_http_module_t c = 37 | { 38 | NGX_MODULE_NULL(6), 39 | &conf_type::create, 40 | NGX_MODULE_NULL(1), 41 | }; 42 | 43 | return &c; 44 | } 45 | public: 46 | static const ngx_module_t& module() 47 | { 48 | static ngx_module_t m = 49 | { 50 | NGX_MODULE_V1, 51 | 52 | ctx(), 53 | cmds(), 54 | 55 | NGX_HTTP_MODULE, 56 | NGX_MODULE_NULL(7), 57 | NGX_MODULE_V1_PADDING 58 | }; 59 | 60 | return m; 61 | } 62 | private: 63 | static char* set_upstream_pass(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) 64 | { 65 | ngx_url_t u; 66 | 67 | u.url = NgxConfig::args(cf)[1]; 68 | u.no_resolve = true; 69 | 70 | auto& lcf = *reinterpret_cast(conf); 71 | 72 | lcf.upstream.upstream = ngx_http_upstream_add(cf, &u, 0); 73 | 74 | if(!lcf.upstream.upstream) 75 | { 76 | return NGX_CONF_ERROR; 77 | } 78 | 79 | NgxHttpCoreModule::handler( 80 | cf, &handler_type::handler); 81 | 82 | return NGX_CONF_OK; 83 | } 84 | }; 85 | 86 | #endif //_NDG_UPSTREAM_INIT_HPP 87 | -------------------------------------------------------------------------------- /legacy/upstream/config: -------------------------------------------------------------------------------- 1 | #./configure --add-module=$HOME/ngx_cpp_dev/modules/test 2 | 3 | ngx_addon_name=ndg_upstream_module 4 | 5 | if test -n "$ngx_module_link"; then 6 | ngx_module_type=HTTP 7 | ngx_module_name=ndg_upstream_module 8 | ngx_module_srcs="$ngx_addon_dir/ModNdgUpstream.cpp" 9 | 10 | . auto/module 11 | else 12 | HTTP_MODULES="$HTTP_MODULES ndg_upstream_module" 13 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ModNdgUpstream.cpp" 14 | fi 15 | -------------------------------------------------------------------------------- /ngxpp/Nginx.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_COMMON_HEADERS_HPP 4 | #define _NGX_COMMON_HEADERS_HPP 5 | 6 | #include // for NGINX_VER... 7 | 8 | extern "C" { 9 | 10 | #include 11 | 12 | // in ngx_http_core_module.h 13 | //#include 14 | 15 | #include 16 | #include 17 | } 18 | 19 | #define ngx_cpp_version 1001000 20 | #define NGX_CPP_VERSION "1.1.0" 21 | 22 | #endif //_NGX_COMMON_HEADERS_HPP 23 | -------------------------------------------------------------------------------- /ngxpp/NginxStream.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_STREAM_HPP 4 | #define _NGX_STREAM_HPP 5 | 6 | #include // for NGINX_VER... 7 | 8 | #if (nginx_version < 1009000) 9 | #error "nginx 1.9.0 and later has stream module" 10 | #endif // nginx 1.9.0 && ngx_stream 11 | 12 | extern "C" { 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | } 21 | 22 | #define ngx_stream_cpp_version 1000000 23 | #define NGX_STREAM_CPP_VERSION "1.0.0" 24 | 25 | #endif // _NGX_STREAM_HPP 26 | 27 | -------------------------------------------------------------------------------- /ngxpp/NgxAll.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_ALL_HPP 4 | #define _NGX_ALL_HPP 5 | 6 | // nginx headers 7 | #include "Nginx.hpp" 8 | 9 | // cpp headers 10 | #include "NgxCppInc.hpp" 11 | 12 | // core classes in namespace ngx{} 13 | #include "NgxCore.hpp" 14 | 15 | // namespace define 16 | #define NGX_HTTP_NAMESPACE_BEGIN namespace ngx { namespace http { 17 | #define NGX_HTTP_NAMESPACE_END }} 18 | #define USING_HTTP_NAMESPACE using namespace ngx::http; 19 | 20 | // http classes 21 | NGX_HTTP_NAMESPACE_BEGIN 22 | 23 | #include "NgxModule.hpp" 24 | #include "NgxHttpModule.hpp" 25 | 26 | #include "NgxRequest.hpp" 27 | #include "NgxFilter.hpp" 28 | #include "NgxUpstream.hpp" 29 | #include "NgxLoadBalance.hpp" 30 | #include "NgxSubRequest.hpp" 31 | 32 | #include "NgxVariable.hpp" 33 | #include "NgxComplexValue.hpp" 34 | 35 | //#include "NgxFactory.hpp" 36 | 37 | NGX_HTTP_NAMESPACE_END 38 | 39 | // open namespace ngx::http 40 | USING_HTTP_NAMESPACE 41 | 42 | #endif //_NGX_ALL_HPP 43 | -------------------------------------------------------------------------------- /ngxpp/NgxAllocator.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_ALLOCATOR_HPP 4 | #define _NGX_ALLOCATOR_HPP 5 | 6 | #include "NgxWrapper.hpp" 7 | 8 | template 9 | class NgxAlloctor : public NgxWrapper 10 | { 11 | public: 12 | typedef NgxWrapper super_type; 13 | typedef NgxAlloctor this_type; 14 | public: 15 | typedef std::size_t size_type; 16 | typedef std::ptrdiff_t difference_type; 17 | typedef T* pointer; 18 | typedef const T* const_pointer; 19 | typedef T& reference; 20 | typedef const T& const_reference; 21 | typedef T value_type; 22 | 23 | template 24 | struct rebind 25 | { 26 | typedef NgxAlloctor other; 27 | }; 28 | public: 29 | NgxAlloctor(ngx_pool_t* p) : super_type(p) 30 | {} 31 | 32 | ~NgxAlloctor() = default; 33 | /* 34 | public: 35 | pointer address(reference r) const 36 | { 37 | return &r; 38 | } 39 | 40 | const_pointer address(const_reference r) const 41 | { 42 | return &r; 43 | } 44 | 45 | size_type max_size() const 46 | { 47 | return std::numeric_limits::max(); 48 | } 49 | */ 50 | public: 51 | pointer allocate(size_type n) 52 | { 53 | return reinterpret_cast( 54 | ngx_pnalloc(get(), n * sizeof(T))); 55 | } 56 | 57 | void deallocate(pointer ptr, size_type n) 58 | { 59 | boost::ignore_unused(n); 60 | ngx_pfree(get(), ptr); 61 | } 62 | /* 63 | public: 64 | bool operator==(const NgxAlloctor& o) const 65 | { 66 | return get() == o.get(); 67 | } 68 | 69 | bool operator!=(const NgxAlloctor& o) const 70 | { 71 | return get() != o.get(); 72 | } 73 | */ 74 | }; 75 | 76 | #ifdef NGX_STD_CONTAINER 77 | #include 78 | 79 | template 80 | using NgxStdVector = std::vector >; 81 | 82 | #endif 83 | 84 | #endif //_NGX_ALLOCATOR_HPP 85 | -------------------------------------------------------------------------------- /ngxpp/NgxArray.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_ARRAY_HPP 4 | #define _NGX_ARRAY_HPP 5 | 6 | #include "NgxPool.hpp" 7 | 8 | template 9 | class NgxArray final : public NgxWrapper 10 | { 11 | public: 12 | typedef NgxWrapper super_type; 13 | typedef NgxArray this_type; 14 | 15 | typedef T value_type; 16 | public: 17 | NgxArray(const NgxPool& p, ngx_uint_t n = 10): 18 | super_type(p.array(n)) 19 | {} 20 | 21 | NgxArray(ngx_array_t* arr):super_type(arr) 22 | {} 23 | 24 | NgxArray(ngx_array_t& arr):super_type(arr) 25 | {} 26 | 27 | ~NgxArray() = default; 28 | public: 29 | ngx_uint_t size() const 30 | { 31 | return get()?get()->nelts:0; 32 | } 33 | 34 | T& operator[](ngx_uint_t i) const 35 | { 36 | NgxException::require(i < size() && get()); 37 | 38 | return elts()[i]; 39 | } 40 | 41 | public: 42 | bool empty() const 43 | { 44 | return get()->nelts == 0; 45 | } 46 | 47 | void clear() const 48 | { 49 | get()->nelts = 0; 50 | } 51 | 52 | public: 53 | template 54 | NgxArray reshape(ngx_uint_t n = 0, ngx_pool_t* pool = nullptr) const 55 | { 56 | auto rc = ngx_array_init(get(), 57 | pool ? pool: get()->pool, 58 | n ? n : get()->nalloc, 59 | sizeof(U) 60 | ); 61 | 62 | NgxException::require(rc); 63 | 64 | return get(); 65 | } 66 | 67 | void reinit(ngx_uint_t n = 0) const 68 | { 69 | reshape(n); 70 | } 71 | public: 72 | template 73 | void visit(V v) const 74 | { 75 | auto p = elts(); 76 | 77 | for(ngx_uint_t i = 0;i < size(); ++i) 78 | { 79 | v(p[i]); 80 | } 81 | } 82 | public: 83 | T& prepare() const 84 | { 85 | auto tmp = ngx_array_push(get()); 86 | 87 | NgxException::require(tmp); 88 | 89 | assert(tmp); 90 | return *reinterpret_cast(tmp); 91 | } 92 | 93 | void push(const T& x) const 94 | { 95 | prepare() = x; 96 | } 97 | public: 98 | void merge(const this_type& a) const 99 | { 100 | auto f = [this](const value_type& v) 101 | { 102 | prepare() = v; 103 | }; 104 | 105 | a.visit(f); 106 | } 107 | private: 108 | T* elts() const 109 | { 110 | return reinterpret_cast(get()->elts); 111 | } 112 | }; 113 | 114 | typedef NgxArray NgxIntArray; 115 | typedef NgxArray NgxUintArray; 116 | 117 | typedef NgxArray NgxStrArray; 118 | typedef NgxArray NgxKvArray; 119 | 120 | #endif //_NGX_ARRAY_HPP 121 | -------------------------------------------------------------------------------- /ngxpp/NgxBuf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_BUF_HPP 4 | #define _NGX_BUF_HPP 5 | 6 | #include "NgxPool.hpp" 7 | 8 | class NgxBuf final : public NgxWrapper 9 | { 10 | public: 11 | typedef NgxWrapper super_type; 12 | typedef NgxBuf this_type; 13 | public: 14 | NgxBuf(const NgxPool& p, std::size_t n): 15 | super_type(p.buffer(n)) 16 | {} 17 | 18 | NgxBuf(ngx_buf_t* buf):super_type(buf) 19 | {} 20 | 21 | NgxBuf(ngx_buf_t& buf):super_type(buf) 22 | {} 23 | 24 | ~NgxBuf() = default; 25 | public: 26 | // readable range 27 | void range(u_char* a, u_char* b) const 28 | { 29 | get()->pos = a; 30 | get()->last = b; 31 | 32 | get()->memory = true; 33 | } 34 | 35 | void boundary(u_char* a, u_char* b) const 36 | { 37 | get()->start = a; 38 | get()->end = b; 39 | } 40 | 41 | ngx_str_t range() const 42 | { 43 | return ngx_str_t{ 44 | static_cast(get()->last - get()->pos), get()->pos}; 45 | } 46 | 47 | ngx_str_t boundary() const 48 | { 49 | return ngx_str_t{ 50 | static_cast(get()->end - get()->start), get()->start}; 51 | } 52 | public: 53 | // convenitable method 54 | void range(ngx_str_t* s) const 55 | { 56 | range(s->data, s->data + s->len); 57 | boundary(s->data, s->data + s->len); 58 | } 59 | 60 | void range(ngx_str_t& s) const 61 | { 62 | range(&s); 63 | } 64 | public: 65 | template 66 | void printf(const Args& ... args) const 67 | { 68 | get()->last = ngx_slprintf(get()->pos, get()->end, args ...); 69 | } 70 | 71 | void copy(u_char* src, size_t n) const 72 | { 73 | get()->last = ngx_copy(get()->pos, src, n); 74 | } 75 | public: 76 | std::size_t size() const 77 | { 78 | return ngx_buf_size(get()); 79 | } 80 | 81 | void clear() const 82 | { 83 | get()->pos = get()->last; 84 | } 85 | 86 | void reset() const 87 | { 88 | get()->pos = get()->start; 89 | get()->last = get()->start; 90 | } 91 | 92 | // ngx_uint_t capacity() const 93 | // { 94 | // return get()->end - get()->start; 95 | // } 96 | 97 | public: 98 | bool empty() const 99 | { 100 | return get()->pos == get()->last; 101 | } 102 | 103 | bool full() const 104 | { 105 | return get()->pos == get()->end; 106 | } 107 | public: 108 | void consume(std::size_t n) const 109 | { 110 | if(n > size()) 111 | { 112 | n = size(); 113 | } 114 | 115 | get()->pos += n; 116 | } 117 | 118 | void produce(std::size_t n) const 119 | { 120 | get()->last += n; 121 | 122 | if(get()->last > get()->end) 123 | { 124 | get()->last = get()->end; 125 | } 126 | } 127 | public: 128 | u_char* begin() const 129 | { 130 | return get()->pos; 131 | } 132 | 133 | u_char* end() const 134 | { 135 | return get()->last; 136 | } 137 | public: 138 | bool memory() const 139 | { 140 | return ngx_buf_in_memory(get()); 141 | } 142 | 143 | bool memoryonly() const 144 | { 145 | return ngx_buf_in_memory_only(get()); 146 | } 147 | 148 | bool special() const 149 | { 150 | return ngx_buf_special(get()); 151 | } 152 | public: 153 | bool last() const 154 | { 155 | return get()->last_buf || get()->last_in_chain; 156 | } 157 | 158 | void finish(bool flag = true) const 159 | { 160 | get()->last_buf = flag; 161 | get()->last_in_chain = flag; 162 | } 163 | }; 164 | 165 | #endif //_NGX_BUF_HPP 166 | -------------------------------------------------------------------------------- /ngxpp/NgxChain.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_CHAIN_HPP 4 | #define _NGX_CHAIN_HPP 5 | 6 | //#include 7 | //#include 8 | 9 | #include "NgxBuf.hpp" 10 | 11 | class NgxChainNode final : public NgxWrapper 12 | { 13 | public: 14 | typedef NgxWrapper super_type; 15 | typedef NgxChainNode this_type; 16 | typedef NgxBuf buffer_type; 17 | public: 18 | NgxChainNode(const NgxPool& p):super_type(p.chain()) 19 | {} 20 | 21 | NgxChainNode(ngx_chain_t* c):super_type(c) 22 | {} 23 | 24 | ~NgxChainNode() = default; 25 | public: 26 | bool last() const 27 | { 28 | return !get()->next; 29 | } 30 | 31 | void link(ngx_chain_t* c) const 32 | { 33 | get()->next = c; 34 | } 35 | 36 | void finish() const 37 | { 38 | return link(nullptr); 39 | } 40 | public: 41 | buffer_type data() const 42 | { 43 | return get()->buf; 44 | } 45 | 46 | void set(ngx_buf_t* ptr) const 47 | { 48 | get()->buf = ptr; 49 | } 50 | public: 51 | void free(ngx_pool_t* pool) const 52 | { 53 | ngx_free_chain(pool, get()); 54 | } 55 | }; 56 | 57 | class NgxChainIterator final: 58 | public boost::iterator_facade< 59 | NgxChainIterator, NgxChainNode, 60 | boost::single_pass_traversal_tag> 61 | { 62 | public: 63 | typedef boost::iterator_facade< 64 | NgxChainIterator, NgxChainNode, 65 | boost::single_pass_traversal_tag> 66 | super_type; 67 | typedef typename super_type::reference reference; 68 | public: 69 | NgxChainIterator(ngx_chain_t* c) : m_p(c) 70 | {} 71 | 72 | NgxChainIterator() = default; 73 | ~NgxChainIterator() = default; 74 | public: 75 | BOOST_EXPLICIT_OPERATOR_BOOL() 76 | 77 | bool operator!() const 78 | { 79 | return !m_p; 80 | } 81 | 82 | private: 83 | friend class boost::iterator_core_access; 84 | 85 | reference dereference() const 86 | { 87 | m_proxy = m_p; 88 | return m_proxy; 89 | } 90 | 91 | void increment() 92 | { 93 | if(!m_p) 94 | { 95 | return; 96 | } 97 | 98 | m_p = m_p->next; 99 | } 100 | 101 | bool equal(NgxChainIterator const& o) const 102 | { 103 | return m_p == o.m_p; 104 | } 105 | private: 106 | ngx_chain_t* m_p = nullptr; 107 | mutable NgxChainNode m_proxy{m_p}; 108 | }; 109 | 110 | class NgxChain final : public NgxWrapper 111 | { 112 | public: 113 | typedef NgxWrapper super_type; 114 | typedef NgxChain this_type; 115 | public: 116 | NgxChain(ngx_chain_t* c):super_type(c) 117 | {} 118 | 119 | ~NgxChain() = default; 120 | public: 121 | typedef NgxChainIterator iterator; 122 | typedef const iterator const_iterator; 123 | 124 | iterator begin() const 125 | { 126 | return iterator(get()); 127 | } 128 | 129 | iterator end() const 130 | { 131 | return iterator(); 132 | } 133 | public: 134 | template 135 | void visit(V v) const 136 | { 137 | for(auto iter = begin(); 138 | iter; ++iter) 139 | { 140 | v(*iter); 141 | } 142 | } 143 | public: 144 | bool empty() const 145 | { 146 | return !get(); 147 | } 148 | 149 | std::size_t size() const 150 | { 151 | std::size_t len = 0; 152 | 153 | for(auto& c : *this) 154 | { 155 | len += c.data().size(); 156 | } 157 | 158 | return len; 159 | } 160 | 161 | public: 162 | ngx_chain_t* head() const 163 | { 164 | return get(); 165 | } 166 | 167 | ngx_chain_t* tail() const 168 | { 169 | auto p = get(); 170 | 171 | for(;p->next;p = p->next); 172 | 173 | return p; 174 | } 175 | 176 | void append(ngx_chain_t* ch) const 177 | { 178 | tail()->next = ch; 179 | } 180 | 181 | public: 182 | // V is a lambda 183 | // [](ngx_chain_t* c){} 184 | // [](const NgxChainNode& c){} 185 | template 186 | iterator trace(V v) const 187 | { 188 | auto p = get(); 189 | 190 | for(;p->next;p = p->next) 191 | { 192 | v(p); 193 | } 194 | 195 | v(p); // last node 196 | 197 | return p; 198 | } 199 | public: 200 | void clear() const 201 | { 202 | for(auto& c : *this) 203 | { 204 | c.data().clear(); 205 | } 206 | } 207 | public: 208 | void copy(u_char* p) const 209 | { 210 | for(auto& c : *this) 211 | { 212 | p = ngx_copy(p, c.data().begin(), c.data().size()); 213 | } 214 | } 215 | public: 216 | ngx_chain_t* free(ngx_pool_t* pool, ngx_chain_t* pos = nullptr) const 217 | { 218 | auto iter = begin(); 219 | decltype(iter) sentinel = pos; 220 | 221 | for(;iter && iter != sentinel;) 222 | { 223 | auto cur = iter; 224 | ++iter; 225 | cur->free(pool); 226 | } 227 | 228 | return pos; 229 | } 230 | }; 231 | 232 | #endif //_NGX_CHAIN_HPP 233 | -------------------------------------------------------------------------------- /ngxpp/NgxClock.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_CLOCK_HPP 4 | #define _NGX_CLOCK_HPP 5 | 6 | //#include "Nginx.hpp" 7 | 8 | class NgxClock final 9 | { 10 | public: 11 | NgxClock() = default; 12 | ~NgxClock() = default; 13 | public: 14 | static const ngx_time_t& now() 15 | { 16 | ngx_time_update(); 17 | 18 | return *ngx_timeofday(); 19 | } 20 | 21 | public: 22 | void reset() 23 | { 24 | m_time = now(); 25 | } 26 | 27 | ngx_time_t delta() const 28 | { 29 | auto t = now(); 30 | 31 | t.sec -= m_time.sec; 32 | t.msec -= m_time.msec; 33 | 34 | return t; 35 | } 36 | 37 | double elapsed() const 38 | { 39 | auto t = delta(); 40 | 41 | return t.sec + t.msec * 1.0 / 1000; 42 | } 43 | public: 44 | static decltype((ngx_current_msec)) msec() 45 | { 46 | return ngx_current_msec; 47 | } 48 | public: 49 | static void sleep(ngx_uint_t sec) 50 | { 51 | ngx_msleep(sec * 1000); 52 | } 53 | 54 | static void msleep(ngx_uint_t msec) 55 | { 56 | ngx_msleep(msec); 57 | } 58 | private: 59 | ngx_time_t m_time = now(); 60 | }; 61 | 62 | #endif //_NGX_CLOCK_HPP 63 | -------------------------------------------------------------------------------- /ngxpp/NgxComplexValue.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_COMPLEX_VALUE_HPP 4 | #define _NGX_COMPLEX_VALUE_HPP 5 | 6 | #include "NgxException.hpp" 7 | #include "NgxValue.hpp" 8 | #include "NgxPool.hpp" 9 | 10 | inline namespace ngx_complex_value_types { 11 | #ifndef ngx_stream_cpp_version //ngx_http_variable 12 | 13 | using ngx_compile_ctx_t = ngx_http_request_t; 14 | 15 | using ngx_compile_complex_value_t = ngx_http_compile_complex_value_t; 16 | using ngx_complex_value_t = ngx_http_complex_value_t; 17 | 18 | static auto ngx_compile_complex_value = &ngx_http_compile_complex_value; 19 | static auto ngx_complex_value = &ngx_http_complex_value; 20 | 21 | #else //ngx_stream_variable 22 | 23 | using ngx_compile_ctx_t = ngx_stream_session_t; 24 | 25 | using ngx_compile_complex_value_t = ngx_stream_compile_complex_value_t; 26 | using ngx_complex_value_t = ngx_stream_complex_value_t; 27 | 28 | static auto ngx_compile_complex_value = &ngx_stream_compile_complex_value; 29 | static auto ngx_complex_value = &ngx_stream_complex_value; 30 | 31 | #endif 32 | } 33 | 34 | class NgxComplexValue final 35 | { 36 | public: 37 | NgxComplexValue() = default; 38 | ~NgxComplexValue() = default; 39 | 40 | public: 41 | void init(ngx_conf_t* cf, ngx_str_t* source) 42 | { 43 | assert(source); 44 | 45 | m_source = *source; 46 | 47 | ngx_compile_complex_value_t ccv; 48 | 49 | NgxValue::memzero(ccv); 50 | 51 | ccv.cf = cf; 52 | ccv.value = source; 53 | ccv.complex_value = &m_cv; 54 | 55 | auto rc = ngx_compile_complex_value(&ccv); 56 | 57 | NgxException::require(rc); 58 | } 59 | 60 | void init(ngx_conf_t* cf, ngx_str_t& source) 61 | { 62 | init(cf,&source); 63 | } 64 | public: 65 | ngx_str_t source() const 66 | { 67 | return m_source; 68 | } 69 | 70 | ngx_str_t str(ngx_compile_ctx_t* r) 71 | { 72 | ngx_str_t value = ngx_null_string; 73 | 74 | auto rc = ngx_complex_value(r, &m_cv, &value); 75 | 76 | NgxException::require(rc); 77 | 78 | return value; 79 | } 80 | private: 81 | ngx_str_t m_source = ngx_null_string; 82 | 83 | ngx_complex_value_t m_cv; 84 | }; 85 | 86 | // alias 87 | //typedef NgxComplexValue NgxScript; 88 | 89 | #endif //_NGX_COMPLEX_VALUE_HPP 90 | -------------------------------------------------------------------------------- /ngxpp/NgxConfig.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_CONFIG_HPP 4 | #define _NGX_CONFIG_HPP 5 | 6 | #include "NgxArray.hpp" 7 | 8 | // #if __cplusplus >= 201402L 9 | // [[deprecated]] // deprecated in future 10 | // #endif 11 | // class NgxCommand final 12 | // { 13 | // private: 14 | // ngx_command_t m_cmd = ngx_null_command; 15 | // public: 16 | // template 17 | // NgxCommand(const ngx_str_t& n, ngx_uint_t t, T set, 18 | // ngx_uint_t c = NGX_CPP_DEV_CMD_OFFSET, 19 | // ngx_uint_t off = 0, void* p = nullptr): 20 | // m_cmd{n, t, set, c, off, p} //do not use () to initilize 21 | // {} 22 | // 23 | // NgxCommand() = default; 24 | // ~NgxCommand() = default; 25 | // public: 26 | // operator const ngx_command_t& () const 27 | // { 28 | // return m_cmd; 29 | // } 30 | // }; 31 | 32 | class NgxTake final 33 | { 34 | public: 35 | NgxTake(ngx_uint_t conf, int m = 0, int n = -1): 36 | m_type(conf | take(m, n)) 37 | {} 38 | ~NgxTake() = default; 39 | public: 40 | operator ngx_uint_t () const 41 | { 42 | return m_type; 43 | } 44 | private: 45 | ngx_uint_t m_type; 46 | private: 47 | static ngx_uint_t take(int m, int n) 48 | { 49 | static 50 | ngx_uint_t takes[] = { 51 | NGX_CONF_NOARGS, 52 | NGX_CONF_TAKE1, 53 | NGX_CONF_TAKE2, 54 | NGX_CONF_TAKE3, 55 | NGX_CONF_TAKE4, 56 | NGX_CONF_TAKE5, 57 | NGX_CONF_TAKE6, 58 | NGX_CONF_TAKE7, 59 | //{8, }, 60 | }; 61 | 62 | if(n < 0 || n < m) 63 | { 64 | return takes[m]; 65 | } 66 | 67 | if(n >= NGX_CONF_MAX_ARGS) 68 | { 69 | return m == 1 ? 70 | NGX_CONF_1MORE : 71 | NGX_CONF_2MORE; 72 | } 73 | 74 | ngx_uint_t tmp = 0; 75 | 76 | for(int i = m; i <= n; ++i) 77 | { 78 | tmp |= takes[i]; 79 | } 80 | 81 | return tmp; 82 | } 83 | 84 | }; 85 | 86 | class NgxConfig final 87 | { 88 | public: 89 | NgxConfig() = default; 90 | ~NgxConfig() = default; 91 | public: 92 | static NgxStrArray args(ngx_conf_t* cf) 93 | { 94 | return NgxStrArray(cf->args); 95 | } 96 | }; 97 | 98 | // for config error message 99 | #define NGX_CONF_ERROR_MSG(s) const_cast(s) 100 | 101 | // #define NGX_CONF_ERROR (void *) -1 102 | #ifdef NGX_CONF_ERROR 103 | #undef NGX_CONF_ERROR 104 | #define NGX_CONF_ERROR reinterpret_cast(-1) 105 | #endif 106 | 107 | // for module's null 108 | #include 109 | 110 | #define NGX_NULL_HELPER(z, n, t) t 111 | #define NGX_MODULE_NULL(n) \ 112 | BOOST_PP_ENUM(n, NGX_NULL_HELPER, nullptr) 113 | 114 | #endif //_NGX_CONFIG_HPP 115 | 116 | 117 | -------------------------------------------------------------------------------- /ngxpp/NgxConnection.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 2 | // Author: Chrono Law 3 | #ifndef _NGX_CONNECTION_HPP 4 | #define _NGX_CONNECTION_HPP 5 | 6 | //#include 7 | //#include 8 | //#include 9 | 10 | #include "NgxWrapper.hpp" 11 | #include "NgxException.hpp" 12 | #include "NgxEvent.hpp" 13 | 14 | class NgxConnection final : public NgxWrapper 15 | { 16 | public: 17 | typedef NgxWrapper super_type; 18 | typedef NgxConnection this_type; 19 | public: 20 | NgxConnection(ngx_connection_t* c) : super_type(c) 21 | {} 22 | 23 | ~NgxConnection() = default; 24 | public: 25 | NgxConnection(ngx_event_t *ev) : 26 | super_type(reinterpret_cast(ev->data)) 27 | {} 28 | 29 | // for http/stream modules 30 | template 31 | NgxConnection(T* x) : super_type(x->connection) 32 | {} 33 | 34 | public: 35 | BOOST_TTI_MEMBER_TYPE(wrapped_type) 36 | 37 | // for NgxSession/NgxRequest 38 | template 39 | NgxConnection(const T& x, 40 | typename boost::enable_if< 41 | boost::tti::valid_member_type< 42 | member_type_wrapped_type> 43 | >::type* p = 0): 44 | NgxConnection(x.get()) 45 | {} 46 | public: 47 | // T = ngx_http_request_t/ngx_stream_session_t 48 | template 49 | T* data() const 50 | { 51 | return reinterpret_cast(get()->data); 52 | } 53 | public: 54 | ngx_event_t* read_event() const 55 | { 56 | return get()->read; 57 | } 58 | 59 | ngx_event_t* write_event() const 60 | { 61 | return get()->write; 62 | } 63 | public: 64 | ssize_t recv(u_char *buf, size_t size) const noexcept 65 | { 66 | return get()->recv(get(), buf, size); 67 | } 68 | 69 | ssize_t send(u_char *buf, size_t size) const noexcept 70 | { 71 | return get()->send(get(), buf, size); 72 | } 73 | public: 74 | ssize_t send(ngx_buf_t *buf) const noexcept 75 | { 76 | return send(buf->pos, ngx_buf_size(buf)); 77 | } 78 | 79 | ngx_chain_t* send(ngx_chain_t *in, off_t limit = 0) const noexcept 80 | { 81 | return get()->send_chain(get(), in, limit); 82 | } 83 | public: 84 | void free() const 85 | { 86 | ngx_free_connection(get()); 87 | } 88 | 89 | void reusable(bool is_reusable) const 90 | { 91 | ngx_reusable_connection(get(), is_reusable); 92 | } 93 | public: 94 | bool closed() const 95 | { 96 | return get()->close; 97 | } 98 | 99 | void close() const 100 | { 101 | ngx_close_connection(get()); 102 | } 103 | 104 | //void http_close() const 105 | //{ 106 | // ngx_http_close_connection(get()); 107 | //} 108 | }; 109 | 110 | 111 | #endif // _NGX_CONNECTION_HPP 112 | -------------------------------------------------------------------------------- /ngxpp/NgxCore.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_CORE_HPP 4 | #define _NGX_CORE_HPP 5 | 6 | // namespace define 7 | #define NGX_NAMESPACE_BEGIN namespace ngx { 8 | #define NGX_NAMESPACE_END } 9 | #define USING_NGX_NAMESPACE using namespace ngx; 10 | 11 | NGX_NAMESPACE_BEGIN 12 | 13 | #include "NgxWrapper.hpp" 14 | 15 | #include "NgxValue.hpp" 16 | #include "NgxException.hpp" 17 | #include "NgxPool.hpp" 18 | #include "NgxAllocator.hpp" 19 | #include "NgxString.hpp" 20 | #include "NgxLog.hpp" 21 | #include "NgxClock.hpp" 22 | #include "NgxDatetime.hpp" 23 | 24 | #include "NgxArray.hpp" 25 | #include "NgxList.hpp" 26 | #include "NgxQueue.hpp" 27 | #include "NgxRbtree.hpp" 28 | #include "NgxBuf.hpp" 29 | #include "NgxChain.hpp" 30 | #include "NgxKeyValue.hpp" 31 | //#include "NgxFile.hpp" 32 | 33 | #include "NgxConfig.hpp" 34 | 35 | #include "NgxDigest.hpp" 36 | #include "NgxTimer.hpp" 37 | 38 | #include "NgxEvent.hpp" 39 | #include "NgxConnection.hpp" 40 | #include "NgxGlobal.hpp" 41 | 42 | #if (NGX_THREADS) 43 | #include "NgxThread.hpp" 44 | #endif //NGX_THREADS 45 | 46 | NGX_NAMESPACE_END 47 | 48 | // open namespace ngx 49 | USING_NGX_NAMESPACE 50 | 51 | #endif //_NGX_CORE_HPP 52 | -------------------------------------------------------------------------------- /ngxpp/NgxCppInc.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_CPPINC_HPP 4 | #define _NGX_CPPINC_HPP 5 | 6 | #if __cplusplus < 201103L 7 | #error "ngx_cpp_module needs C++11 implementation!" 8 | #endif 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | // ignore_unused/explicit_bool since boost 1.56 19 | #if BOOST_VERSION < 105600 20 | namespace boost { 21 | template 22 | inline void ignore_unused(Ts const& ...){} 23 | } 24 | 25 | #define BOOST_EXPLICIT_OPERATOR_BOOL()\ 26 | BOOST_FORCEINLINE explicit operator bool () const\ 27 | {\ 28 | return !this->operator! ();\ 29 | } 30 | #else 31 | #include 32 | #include 33 | #endif 34 | 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | //#include 42 | 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | #endif // _NGX_CPPINC_HPP 58 | -------------------------------------------------------------------------------- /ngxpp/NgxDatetime.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_DATETIME_HPP 4 | #define _NGX_DATETIME_HPP 5 | 6 | //#include "Nginx.hpp" 7 | 8 | class NgxDatetime final 9 | { 10 | public: 11 | NgxDatetime() = default; 12 | ~NgxDatetime() = default; 13 | public: 14 | static std::time_t since() 15 | { 16 | return ngx_time(); 17 | } 18 | 19 | static ngx_str_t today() 20 | { 21 | ngx_tm_t tm; 22 | 23 | //ngx_gmtime(since(), &tm); 24 | ngx_localtime(since(), &tm); 25 | 26 | static u_char buf[20] = {}; 27 | 28 | auto p = ngx_snprintf(buf, 20, 29 | "%d-%02d-%02d", 30 | tm.ngx_tm_year, tm.ngx_tm_mon, tm.ngx_tm_mday); 31 | 32 | return ngx_str_t{static_cast(p - buf), buf}; 33 | } 34 | public: 35 | static ngx_str_t http(std::time_t t = since()) 36 | { 37 | static u_char buf[50] = {}; 38 | 39 | auto p = ngx_http_time(buf, t); 40 | 41 | return ngx_str_t{static_cast(p - buf), buf}; 42 | } 43 | 44 | static std::time_t http(ngx_str_t& str) 45 | { 46 | return ngx_parse_http_time(str.data, str.len); 47 | } 48 | }; 49 | 50 | #endif //_NGX_DATETIME_HPP 51 | -------------------------------------------------------------------------------- /ngxpp/NgxDigest.hpp: -------------------------------------------------------------------------------- 1 | // Author: Chrono Law 2 | // Copyright (c) 2015-2017 3 | #ifndef _NGX_DIGEST_HPP 4 | #define _NGX_DIGEST_HPP 5 | 6 | //extern "C" { 7 | //#include 8 | //#include 9 | //#include 10 | //} 11 | 12 | //#include 13 | //#include "Nginx.hpp" 14 | 15 | struct NgxMd5Meta 16 | { 17 | typedef ngx_md5_t ctx_type; 18 | 19 | static constexpr int len = 16; 20 | 21 | static constexpr auto init_func = &ngx_md5_init; 22 | static constexpr auto update_func = &ngx_md5_update; 23 | static constexpr auto final_func = &ngx_md5_final; 24 | }; 25 | 26 | struct NgxSha1Meta 27 | { 28 | typedef ngx_sha1_t ctx_type; 29 | 30 | static constexpr int len = 20; 31 | 32 | static constexpr auto init_func = &ngx_sha1_init; 33 | static constexpr auto update_func = &ngx_sha1_update; 34 | static constexpr auto final_func = &ngx_sha1_final; 35 | }; 36 | 37 | struct NgxMurmurHash2Meta 38 | { 39 | static constexpr auto update_func = &ngx_murmur_hash2; 40 | }; 41 | 42 | template 43 | class NgxDigest final 44 | { 45 | public: 46 | typedef DigestMeta meta; 47 | typedef boost::string_ref string_ref_type; 48 | public: 49 | NgxDigest() //= default; 50 | { 51 | init(); 52 | } 53 | ~NgxDigest() = default; 54 | public: 55 | void init() 56 | { 57 | meta::init_func(&m_ctx); 58 | } 59 | 60 | void update(const void* data, std::size_t len) 61 | { 62 | meta::update_func(&m_ctx, data, len); 63 | } 64 | 65 | const u_char* final() 66 | { 67 | meta::final_func(m_buf, &m_ctx); 68 | 69 | return m_buf; 70 | } 71 | 72 | ngx_str_t str() 73 | { 74 | //final(); 75 | 76 | ngx_hex_dump(m_hex, m_buf, sizeof(m_buf)); 77 | 78 | return ngx_str_t{sizeof(m_hex), m_hex}; 79 | } 80 | public: 81 | ngx_str_t operator()(const void* data, std::size_t len) 82 | { 83 | init(); 84 | update(data, len); 85 | final(); 86 | 87 | return str(); 88 | } 89 | 90 | ngx_str_t operator()(string_ref_type str) 91 | { 92 | return operator()(str.data(), str.size()); 93 | } 94 | private: 95 | typename meta::ctx_type m_ctx; 96 | 97 | u_char m_buf[meta::len]; 98 | u_char m_hex[meta::len*2]; 99 | }; 100 | 101 | template<> 102 | class NgxDigest final 103 | { 104 | public: 105 | typedef NgxMurmurHash2Meta meta; 106 | typedef boost::string_ref string_ref_type; 107 | public: 108 | NgxDigest() = default; 109 | ~NgxDigest() = default; 110 | public: 111 | uint32_t operator()(const void* data, std::size_t len) 112 | { 113 | return meta::update_func((u_char*)data, len); 114 | } 115 | 116 | uint32_t operator()(string_ref_type str) 117 | { 118 | return operator()(str.data(), str.size()); 119 | } 120 | }; 121 | 122 | typedef NgxDigest NgxMd5; 123 | typedef NgxDigest NgxSha1; 124 | typedef NgxDigest NgxMurmurHash2; 125 | 126 | #endif //_NGX_DIGEST_HPP 127 | -------------------------------------------------------------------------------- /ngxpp/NgxEvent.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_EVENT_HPP 4 | #define _NGX_EVENT_HPP 5 | 6 | //#include "Nginx.hpp" 7 | #include "NgxWrapper.hpp" 8 | #include "NgxException.hpp" 9 | 10 | class NgxEvent : public NgxWrapper 11 | { 12 | public: 13 | typedef NgxWrapper super_type; 14 | typedef NgxEvent this_type; 15 | public: 16 | NgxEvent(ngx_event_t* ev) : super_type(ev) 17 | {} 18 | 19 | NgxEvent(ngx_event_t& ev) : super_type(ev) 20 | {} 21 | 22 | ~NgxEvent() = default; 23 | public: 24 | template 25 | void data(T* p) const 26 | { 27 | get()->data = p; 28 | } 29 | 30 | template 31 | void data(T& v) const 32 | { 33 | get()->data = &v; 34 | } 35 | 36 | public: 37 | template 38 | T* data() const 39 | { 40 | return reinterpret_cast(get()->data); 41 | } 42 | 43 | ngx_connection_t* connection() const 44 | { 45 | return data(); 46 | } 47 | public: 48 | template 49 | void handler(F f) const 50 | { 51 | get()->handler = f; 52 | } 53 | 54 | // ngx_nil = ngx_del_timer 55 | void timeout(ngx_msec_t timer, bool reset = false) const 56 | { 57 | if(get()->timer_set) 58 | { 59 | if(timer == ngx_nil) 60 | { 61 | ngx_del_timer(get()); 62 | return; 63 | } 64 | 65 | if(!reset) 66 | { 67 | return; 68 | } 69 | } 70 | 71 | ngx_add_timer(get(), timer); 72 | } 73 | 74 | public: 75 | bool ready() const 76 | { 77 | return get()->ready; 78 | } 79 | 80 | bool expired() const 81 | { 82 | return get()->timedout; 83 | } 84 | public: 85 | void process() const 86 | { 87 | get()->handler(get()); 88 | } 89 | }; 90 | 91 | class NgxReadEvent final: public NgxEvent 92 | { 93 | public: 94 | typedef NgxEvent super_type; 95 | typedef NgxReadEvent this_type; 96 | public: 97 | NgxReadEvent(ngx_event_t* ev) : super_type(ev) 98 | { 99 | assert(!ev->write); 100 | } 101 | 102 | NgxReadEvent(ngx_event_t& ev) : super_type(ev) 103 | {} 104 | 105 | ~NgxReadEvent() = default; 106 | public: 107 | void wait(ngx_uint_t flags = 0) const 108 | { 109 | auto rc = ngx_handle_read_event(get(), flags); 110 | 111 | NgxException::require(rc); 112 | } 113 | 114 | void wait_for(ngx_msec_t timer, bool reset = false, ngx_uint_t flags = 0) const 115 | { 116 | timeout(timer, reset); 117 | wait(flags); 118 | } 119 | }; 120 | 121 | class NgxWriteEvent final: public NgxEvent 122 | { 123 | public: 124 | typedef NgxEvent super_type; 125 | typedef NgxWriteEvent this_type; 126 | public: 127 | NgxWriteEvent(ngx_event_t* ev) : super_type(ev) 128 | { 129 | assert(ev->write); 130 | } 131 | 132 | NgxWriteEvent(ngx_event_t& ev) : super_type(ev) 133 | {} 134 | 135 | ~NgxWriteEvent() = default; 136 | public: 137 | void wait(size_t lowat = 0) const 138 | { 139 | auto rc = ngx_handle_write_event(get(), lowat); 140 | 141 | NgxException::require(rc); 142 | } 143 | 144 | void wait_for(ngx_msec_t timer, bool reset = false, size_t lowat = 0) const 145 | { 146 | timeout(timer, reset); 147 | wait(lowat); 148 | } 149 | }; 150 | #endif //_NGX_EVENT_HPP 151 | -------------------------------------------------------------------------------- /ngxpp/NgxException.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_EXCEPT_HPP 4 | #define _NGX_EXCEPT_HPP 5 | 6 | //#include 7 | //#include 8 | //#include 9 | //#include 10 | 11 | //#include "Nginx.hpp" 12 | 13 | class NgxException final : public virtual std::exception, 14 | public virtual boost::exception 15 | { 16 | public: 17 | //typedef NgxException this_type; 18 | typedef boost::string_ref string_ref_type; 19 | public: 20 | //NgxException() = default; 21 | 22 | NgxException(ngx_int_t x, string_ref_type msg): 23 | m_code(x), m_msg(msg) 24 | {} 25 | 26 | NgxException(ngx_int_t x = NGX_ERROR): 27 | NgxException(x, "") 28 | {} 29 | 30 | NgxException(string_ref_type msg): 31 | NgxException(NGX_ERROR, msg) 32 | {} 33 | 34 | virtual ~NgxException() noexcept 35 | {} 36 | public: 37 | static void raise(ngx_int_t rc = NGX_ERROR, string_ref_type msg = "") 38 | { 39 | throw NgxException(rc, msg); 40 | } 41 | 42 | static void require(bool cond, ngx_int_t e = NGX_ERROR, string_ref_type msg = "") 43 | { 44 | if(!cond) 45 | { 46 | raise(e, msg); 47 | } 48 | } 49 | 50 | static void require(ngx_int_t rc, ngx_int_t x = NGX_OK, string_ref_type msg = "") 51 | { 52 | require(rc == x, rc, msg); 53 | } 54 | 55 | template 56 | static void require(T* p, ngx_int_t e = NGX_ERROR, string_ref_type msg = "") 57 | { 58 | require(p != nullptr, e, msg); 59 | } 60 | 61 | static void fail(bool cond, ngx_int_t e = NGX_ERROR, string_ref_type msg = "") 62 | { 63 | if(cond) 64 | { 65 | raise(e, msg); 66 | } 67 | } 68 | 69 | public: 70 | ngx_int_t code() const 71 | { 72 | return m_code; 73 | } 74 | 75 | virtual const char* what() const noexcept override 76 | { 77 | return m_msg.c_str(); 78 | } 79 | private: 80 | ngx_int_t m_code = NGX_ERROR; 81 | std::string m_msg; 82 | }; 83 | 84 | #endif //_NGX_EXCEPT_HPP 85 | 86 | -------------------------------------------------------------------------------- /ngxpp/NgxFilter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_FILTER_HPP 4 | #define _NGX_FILTER_HPP 5 | 6 | // use Tag to instance static var 7 | template 8 | class NgxFilter final 9 | { 10 | public: 11 | typedef NgxFilter this_type; 12 | typedef ngx_http_output_header_filter_pt header_filter_ptr; 13 | typedef ngx_http_output_body_filter_pt body_filter_ptr; 14 | 15 | NgxFilter() = default; 16 | ~NgxFilter() = default; 17 | 18 | public: 19 | static void init(header_filter_ptr header_filter = nullptr, 20 | body_filter_ptr body_filter = nullptr) 21 | { 22 | if(header_filter) 23 | { 24 | set(ngx_http_top_header_filter, header_filter); 25 | } 26 | 27 | if(body_filter) 28 | { 29 | set(ngx_http_top_body_filter, body_filter); 30 | } 31 | } 32 | public: 33 | static ngx_int_t next(ngx_http_request_t* r) 34 | { 35 | return next()(r); 36 | } 37 | 38 | static ngx_int_t next(ngx_http_request_t* r, ngx_chain_t *chain) 39 | { 40 | return next()(r, chain); 41 | } 42 | private: 43 | template 44 | static void set(T& top, T p) 45 | { 46 | next() = top; 47 | top = p; 48 | } 49 | 50 | template 51 | static T& next() 52 | { 53 | static T next_filter; 54 | 55 | return next_filter; 56 | } 57 | }; 58 | 59 | // now only request body filter 60 | template 61 | class NgxRequestFilter final 62 | { 63 | public: 64 | typedef NgxRequestFilter this_type; 65 | typedef ngx_http_request_body_filter_pt body_filter_ptr; 66 | 67 | NgxRequestFilter() = default; 68 | ~NgxRequestFilter() = default; 69 | 70 | public: 71 | static void init(body_filter_ptr body_filter = nullptr) 72 | { 73 | if(body_filter) 74 | { 75 | set(ngx_http_top_request_body_filter, body_filter); 76 | } 77 | } 78 | public: 79 | static ngx_int_t next(ngx_http_request_t* r, ngx_chain_t *chain) 80 | { 81 | return next()(r, chain); 82 | } 83 | private: 84 | template 85 | static void set(T& top, T p) 86 | { 87 | next() = top; 88 | top = p; 89 | } 90 | 91 | template 92 | static T& next() 93 | { 94 | static T next_filter; 95 | 96 | return next_filter; 97 | } 98 | }; 99 | 100 | #endif //_NGX_FILTER_HPP 101 | -------------------------------------------------------------------------------- /ngxpp/NgxGlobal.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_GLOBAL_HPP 4 | #define _NGX_GLOBAL_HPP 5 | 6 | //#include 7 | 8 | //#include "Nginx.hpp" 9 | 10 | // decltype((xxx)) get the type of expressions! 11 | #define DECL_VAR(x, y) decltype((y)) x = y 12 | 13 | // apis: os(), err(), event(), process(), signal(), cycle(), env() 14 | class NgxGlobal final 15 | { 16 | public: 17 | NgxGlobal() = default; 18 | ~NgxGlobal() = default; 19 | public: 20 | struct os_info_t final : boost::noncopyable 21 | { 22 | DECL_VAR(pagesize, ngx_pagesize); 23 | DECL_VAR(cacheline_size, ngx_cacheline_size); 24 | DECL_VAR(pagesize_shift, ngx_pagesize_shift); 25 | 26 | DECL_VAR(ncpu, ngx_ncpu); 27 | DECL_VAR(max_sockets, ngx_max_sockets); 28 | DECL_VAR(inherited_nonblocking, ngx_inherited_nonblocking); 29 | DECL_VAR(tcp_nodelay_and_tcp_nopush, ngx_tcp_nodelay_and_tcp_nopush); 30 | 31 | // ngx_recv/ngx_send 32 | DECL_VAR(io, ngx_os_io); 33 | }; 34 | 35 | static os_info_t& os() 36 | { 37 | static os_info_t o; 38 | return o; 39 | } 40 | public: 41 | struct errno_info_t final : boost::noncopyable 42 | { 43 | DECL_VAR(no, ngx_errno); 44 | DECL_VAR(socket, ngx_socket_errno); 45 | }; 46 | 47 | static errno_info_t& err() 48 | { 49 | static errno_info_t e; 50 | return e; 51 | } 52 | public: 53 | struct process_info_t final : boost::noncopyable 54 | { 55 | // process/worker id 56 | DECL_VAR(pid, ngx_pid); 57 | 58 | #if (nginx_version >= 1009001) 59 | DECL_VAR(worker, ngx_worker); 60 | #endif 61 | 62 | // process flag = NGX_PROCESS_MASTER/NGX_PROCESS_SINGLE/... 63 | DECL_VAR(type, ngx_process); 64 | 65 | DECL_VAR(new_binary, ngx_new_binary); 66 | 67 | DECL_VAR(daemonized, ngx_daemonized); 68 | DECL_VAR(exiting, ngx_exiting); 69 | 70 | DECL_VAR(channel, ngx_channel); 71 | DECL_VAR(slot, ngx_process_slot); 72 | DECL_VAR(last, ngx_last_process); 73 | 74 | // array for all processes 75 | DECL_VAR(array, ngx_processes); 76 | }; 77 | 78 | static process_info_t& process() 79 | { 80 | static process_info_t p; 81 | return p; 82 | } 83 | public: 84 | struct event_info_t final : boost::noncopyable 85 | { 86 | // ngx_add_event/ngx_del_event/... 87 | DECL_VAR(actions, ngx_event_actions); 88 | DECL_VAR(io, ngx_io); 89 | 90 | // sigalarm flag 91 | DECL_VAR(timer_alarm, ngx_event_timer_alarm); 92 | 93 | // epoll/kqueue flags, NGX_CLEAR_EVENT(EPOLLET) 94 | DECL_VAR(flags, ngx_event_flags); 95 | 96 | // flags 97 | DECL_VAR(use_accept_mutex, ngx_use_accept_mutex); 98 | DECL_VAR(accept_events, ngx_accept_events); 99 | DECL_VAR(accept_mutex_held, ngx_accept_mutex_held); 100 | DECL_VAR(accept_disabled, ngx_accept_disabled); 101 | 102 | // delay time in ms 103 | DECL_VAR(accept_mutex_delay, ngx_accept_mutex_delay); 104 | 105 | // queue 106 | DECL_VAR(posted_accept, ngx_posted_accept_events); 107 | DECL_VAR(posted, ngx_posted_events); 108 | }; 109 | 110 | static event_info_t& event() 111 | { 112 | static event_info_t e; 113 | return e; 114 | } 115 | public: 116 | struct signal_info_t final : boost::noncopyable 117 | { 118 | DECL_VAR(alrm, ngx_sigalrm); 119 | DECL_VAR(quit, ngx_quit); 120 | DECL_VAR(terminate, ngx_terminate); 121 | DECL_VAR(exiting, ngx_exiting); 122 | DECL_VAR(reap, ngx_reap); //sigchld, reopen child 123 | DECL_VAR(reconfigure, ngx_reconfigure); 124 | }; 125 | 126 | static signal_info_t& signal() 127 | { 128 | static signal_info_t s; 129 | return s; 130 | } 131 | public: 132 | // we can't use declyte(xxx)& because keyword 'volatile' 133 | struct cycle_info_t final : boost::noncopyable 134 | { 135 | DECL_VAR(connection_n, ngx_cycle->connection_n); 136 | 137 | DECL_VAR(conf_file, ngx_cycle->conf_file); 138 | DECL_VAR(conf_param, ngx_cycle->conf_param); 139 | DECL_VAR(conf_prefix, ngx_cycle->conf_prefix); 140 | DECL_VAR(prefix, ngx_cycle->prefix); 141 | DECL_VAR(hostname, ngx_cycle->hostname); 142 | }; 143 | 144 | static cycle_info_t& cycle() 145 | { 146 | static cycle_info_t c; 147 | 148 | return c; 149 | } 150 | public: 151 | // some macro constants 152 | struct env_info_t final : boost::noncopyable 153 | { 154 | // in nginx.h 155 | ngx_str_t version = ngx_string(NGINX_VER); 156 | ngx_str_t build = ngx_string(NGINX_VER_BUILD); 157 | 158 | // in objs/ngx_auto_config.h 159 | ngx_str_t configure = ngx_string(NGX_CONFIGURE); 160 | ngx_str_t compiler = ngx_string(NGX_COMPILER); 161 | }; 162 | 163 | static env_info_t& env() 164 | { 165 | static env_info_t e; 166 | return e; 167 | } 168 | }; 169 | 170 | #undef DECL_VAR 171 | 172 | #endif //_NGX_GLOBAL_HPP 173 | -------------------------------------------------------------------------------- /ngxpp/NgxHeaders.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_HEADERS_HPP 4 | #define _NGX_HEADERS_HPP 5 | 6 | //#include 7 | //#include 8 | 9 | #include "NgxList.hpp" 10 | #include "NgxString.hpp" 11 | 12 | // T = ngx_http_headers_in_t/ngx_http_headers_out_t 13 | template 15 | class NgxHeaders final : public NgxWrapper 16 | { 17 | public: 18 | typedef boost::string_ref string_ref_type; 19 | 20 | typedef NgxWrapper super_type; 21 | typedef typename super_type::wrapped_type ngx_headers_type; 22 | 23 | typedef NgxList ngx_headers_list_type; 24 | typedef ngx_table_elt_t kv_type; 25 | 26 | public: 27 | NgxHeaders(ngx_headers_type& h): 28 | super_type(h), 29 | m_headers(h.headers) 30 | {} 31 | 32 | NgxHeaders(ngx_headers_type* h):NgxHeaders(*h) 33 | {} 34 | 35 | NgxHeaders(ngx_http_request_t* r): 36 | NgxHeaders(r->*ptr) 37 | {} 38 | 39 | ~NgxHeaders() = default; 40 | public: 41 | const ngx_headers_list_type& list() const 42 | { 43 | return m_headers; 44 | } 45 | 46 | bool has(string_ref_type key) const 47 | { 48 | return find(key) != list().end(); 49 | } 50 | 51 | ngx_str_t operator[](string_ref_type key) const 52 | { 53 | auto p = find(key); 54 | 55 | if(p == list().end()) 56 | { 57 | return ngx_null_string; 58 | } 59 | 60 | return p->value; 61 | } 62 | 63 | ngx_str_t operator[](const char* key) const 64 | { 65 | return operator[](string_ref_type(key)); 66 | } 67 | public: 68 | void add(const kv_type& kv) const 69 | { 70 | auto& tmp = list().prepare(); 71 | 72 | tmp = kv; 73 | if(!tmp.hash) 74 | { 75 | tmp.hash = 1; 76 | } 77 | } 78 | 79 | void remove(string_ref_type key) const 80 | { 81 | auto p = find(key); 82 | 83 | if(p == list().end()) 84 | { 85 | return; 86 | } 87 | 88 | p->hash = 0; 89 | } 90 | 91 | public: 92 | ngx_headers_list_type::iterator find(string_ref_type key) const 93 | { 94 | auto v = [&](const kv_type& kv) 95 | { 96 | //if(!kv.hash) 97 | //{ 98 | // return false; 99 | //} 100 | 101 | return boost::iequals( 102 | NgxString(kv.key).str(), key); 103 | }; 104 | 105 | return list().find(v); 106 | } 107 | private: 108 | ngx_headers_list_type m_headers; 109 | }; 110 | 111 | typedef NgxHeaders< 112 | ngx_http_headers_in_t, &ngx_http_request_t::headers_in> 113 | NgxHeadersIn; 114 | 115 | typedef NgxHeaders< 116 | ngx_http_headers_out_t, &ngx_http_request_t::headers_out> 117 | NgxHeadersOut; 118 | 119 | //#include 120 | 121 | class NgxHeadersChecker final 122 | { 123 | public: 124 | template 125 | void operator()(T& h) 126 | { 127 | //std::cout << "headers "<< std::endl; 128 | 129 | // print headers 130 | auto v = [](ngx_table_elt_t& x) 131 | { 132 | // atention! must use & to print ngx_str_t! 133 | ngx_log_stderr(0, "%V<=>%V", &x.key, &x.value); 134 | 135 | //std::cout << x.key << "<=>"<< x.value << std::endl; 136 | }; 137 | 138 | h.list().visit(v); 139 | } 140 | }; 141 | 142 | #endif //_NGX_HEADERS_HPP 143 | -------------------------------------------------------------------------------- /ngxpp/NgxHttpModule.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_HTTP_MODULE_HPP 4 | #define _NGX_HTTP_MODULE_HPP 5 | 6 | #include "NgxModule.hpp" 7 | #include "NgxArray.hpp" 8 | 9 | class NgxHttpCoreModule final : 10 | public NgxModule 13 | { 14 | public: 15 | typedef NgxModule 18 | super_type; 19 | typedef NgxHttpCoreModule this_type; 20 | public: 21 | NgxHttpCoreModule() : super_type(ngx_http_core_module) 22 | {} 23 | ~NgxHttpCoreModule() = default; 24 | public: 25 | // content handler 26 | template 27 | static void handler(ngx_conf_t* cf, F f) 28 | { 29 | instance().conf().loc(cf).handler = f; 30 | } 31 | 32 | // phase handler 33 | template 34 | static void handler(ngx_conf_t* cf, F f, ngx_http_phases p) 35 | { 36 | auto& c = instance().conf().main(cf); 37 | 38 | typedef NgxArray handler_array_t; 39 | 40 | assert(p <= NGX_HTTP_LOG_PHASE); 41 | handler_array_t arr(c.phases[p].handlers); 42 | arr.push(f); 43 | } 44 | 45 | public: 46 | static NgxHttpCoreModule& instance() 47 | { 48 | static NgxHttpCoreModule m; 49 | return m; 50 | } 51 | }; 52 | 53 | class NgxHttpUpstreamModule final : 54 | public NgxModule 57 | { 58 | public: 59 | typedef NgxModule 62 | super_type; 63 | typedef NgxHttpUpstreamModule this_type; 64 | public: 65 | NgxHttpUpstreamModule() : super_type(ngx_http_upstream_module) 66 | {} 67 | ~NgxHttpUpstreamModule() = default; 68 | public: 69 | static NgxHttpUpstreamModule& instance() 70 | { 71 | static NgxHttpUpstreamModule m; 72 | return m; 73 | } 74 | public: 75 | template 76 | static void init(ngx_conf_t* cf, F f, ngx_uint_t flags = 0) 77 | { 78 | auto& uscf = instance().conf().srv(cf); 79 | 80 | NgxException::fail(uscf.peer.init_upstream); 81 | 82 | uscf.peer.init_upstream = f; 83 | uscf.flags = flags; 84 | } 85 | }; 86 | 87 | #endif //_NGX_HTTP_MODULE_HPP 88 | -------------------------------------------------------------------------------- /ngxpp/NgxKeyValue.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_KEYVALUE_HPP 4 | #define _NGX_KEYVALUE_HPP 5 | 6 | //#include "Nginx.hpp" 7 | 8 | // ngx_string.h 9 | // 10 | // typedef struct { 11 | // ngx_str_t key; 12 | // ngx_str_t value; 13 | // } ngx_keyval_t; 14 | typedef ngx_keyval_t NgxKeyValue; 15 | 16 | // ngx_hash.h 17 | // 18 | // typedef struct { 19 | // ngx_uint_t hash; 20 | // ngx_str_t key; 21 | // ngx_str_t value; 22 | // u_char *lowcase_key; 23 | // } ngx_table_elt_t; 24 | typedef ngx_table_elt_t NgxHashedKeyValue; 25 | 26 | #endif // _NGX_KEYVALUE_HPP 27 | -------------------------------------------------------------------------------- /ngxpp/NgxList.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_LIST_HPP 4 | #define _NGX_LIST_HPP 5 | 6 | //#include 7 | //#include 8 | 9 | #include "NgxPool.hpp" 10 | 11 | template 12 | class NgxListIterator final : 13 | public boost::iterator_facade< 14 | NgxListIterator, T, 15 | boost::single_pass_traversal_tag> 16 | { 17 | public: 18 | typedef boost::iterator_facade< 19 | NgxListIterator, T, 20 | boost::single_pass_traversal_tag> 21 | super_type; 22 | typedef typename super_type::reference reference; 23 | public: 24 | NgxListIterator(ngx_list_t* l): 25 | m_part(&l->part), 26 | m_data(static_cast(m_part->elts)) 27 | {} 28 | 29 | NgxListIterator() = default; 30 | ~NgxListIterator() = default; 31 | public: 32 | NgxListIterator(NgxListIterator const&) = default; 33 | NgxListIterator& operator=(const NgxListIterator&) = default; 34 | public: 35 | BOOST_EXPLICIT_OPERATOR_BOOL() 36 | 37 | // check invalid 38 | bool operator!() const 39 | { 40 | return !m_part || !m_data || !m_part->nelts; 41 | } 42 | 43 | private: 44 | friend class boost::iterator_core_access; 45 | 46 | reference dereference() const 47 | { 48 | NgxException::require(m_data); 49 | return m_data[m_count]; 50 | } 51 | 52 | void increment() 53 | { 54 | if(!m_part || !m_data) 55 | { 56 | return; 57 | } 58 | 59 | ++m_count; 60 | 61 | if(m_count >= m_part->nelts) 62 | { 63 | m_count = 0; 64 | m_part = m_part->next; 65 | 66 | m_data = m_part? 67 | static_cast(m_part->elts): 68 | nullptr; 69 | } 70 | } 71 | 72 | bool equal(NgxListIterator const& o) const 73 | { 74 | return m_part == o.m_part && 75 | m_data == o.m_data && 76 | m_count == o.m_count; 77 | } 78 | private: 79 | ngx_list_part_t* m_part = nullptr; 80 | T* m_data = nullptr; 81 | ngx_uint_t m_count = 0; 82 | }; 83 | 84 | template 85 | class NgxList final : public NgxWrapper 86 | { 87 | public: 88 | typedef NgxWrapper super_type; 89 | typedef NgxList this_type; 90 | 91 | typedef T value_type; 92 | public: 93 | NgxList(const NgxPool& p, ngx_uint_t n = 10): 94 | super_type(p.list(n)) 95 | {} 96 | 97 | NgxList(ngx_list_t* l):super_type(l) 98 | {} 99 | 100 | NgxList(ngx_list_t& l):super_type(&l) 101 | {} 102 | 103 | ~NgxList() = default; 104 | public: 105 | T& prepare() const 106 | { 107 | auto tmp = ngx_list_push(get()); 108 | 109 | NgxException::require(tmp); 110 | 111 | assert(tmp); 112 | return *reinterpret_cast(tmp); 113 | } 114 | 115 | void push(const T& x) const 116 | { 117 | prepare() = x; 118 | } 119 | public: 120 | bool empty() const 121 | { 122 | return !get()->part.nelts; 123 | } 124 | 125 | public: 126 | void clear() const 127 | { 128 | get()->part.nelts = 0; 129 | get()->part.next = nullptr; 130 | get()->last = &get()->part; 131 | } 132 | public: 133 | template 134 | NgxList reshape(ngx_uint_t n = 0, ngx_pool_t* pool = nullptr) const 135 | { 136 | auto rc = ngx_list_init(get(), 137 | pool ? pool: get()->pool, 138 | n ? n : get()->nalloc, 139 | sizeof(U) 140 | ); 141 | 142 | NgxException::require(rc); 143 | 144 | return get(); 145 | } 146 | 147 | void reinit(ngx_uint_t n = 0) const 148 | { 149 | reshape(n); 150 | } 151 | public: 152 | void merge(const this_type& l) const 153 | { 154 | auto f = [this](const value_type& v) 155 | { 156 | prepare() = v; 157 | }; 158 | 159 | l.visit(f); 160 | } 161 | public: 162 | typedef NgxListIterator iterator; 163 | typedef const iterator const_iterator; 164 | 165 | iterator begin() const 166 | { 167 | return iterator(get()); 168 | } 169 | 170 | iterator end() const 171 | { 172 | return iterator(); 173 | } 174 | public: 175 | template 176 | void visit(V v) const 177 | { 178 | auto iter = begin(); 179 | for(; iter; ++iter) 180 | { 181 | v(*iter); 182 | } 183 | } 184 | public: 185 | // use predicate to find some value 186 | template 187 | iterator find(Predicate p) const 188 | { 189 | auto iter = begin(); 190 | for(; iter; ++iter) 191 | { 192 | if(p(*iter)) 193 | { 194 | return iter; 195 | } 196 | } 197 | 198 | return end(); 199 | } 200 | }; 201 | 202 | #endif //_NGX_LIST_HPP 203 | -------------------------------------------------------------------------------- /ngxpp/NgxLoadBalance.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_LOAD_BALANCE_HPP 4 | #define _NGX_LOAD_BALANCE_HPP 5 | 6 | #include "NgxPool.hpp" 7 | 8 | template 12 | class NgxLoadBalance final 13 | { 14 | typedef ngx_http_upstream_rr_peer_data_t peer_data_t; 15 | typedef ngx_http_upstream_srv_conf_t srv_conf_t; 16 | public: 17 | static void init(ngx_conf_t *cf, srv_conf_t* us, 18 | ngx_http_upstream_init_peer_pt init_peer) 19 | { 20 | auto rc = ngx_http_upstream_init_round_robin(cf, us); 21 | 22 | NgxException::require(rc); 23 | 24 | us->peer.init = init_peer; 25 | } 26 | public: 27 | static T& init(ngx_http_request_t* r, srv_conf_t* us) 28 | { 29 | auto& peer_data = *NgxPool(r).alloc(); 30 | 31 | r->upstream->peer.data = &(peer_data.*ptr); 32 | 33 | auto rc = ngx_http_upstream_init_round_robin_peer(r, us); 34 | 35 | NgxException::require(rc); 36 | 37 | r->upstream->peer.get = get_peer; 38 | r->upstream->peer.free = (free_peer != nullptr)?free_peer: 39 | r->upstream->peer.free; 40 | 41 | return peer_data; 42 | } 43 | 44 | public: 45 | static ngx_int_t round_robin(ngx_peer_connection_t* pc, void* data) 46 | { 47 | return ngx_http_upstream_get_round_robin_peer(pc, data); 48 | } 49 | }; 50 | 51 | #endif //_NGX_LOAD_BALANCE_HPP 52 | -------------------------------------------------------------------------------- /ngxpp/NgxLog.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_LOG_HPP 4 | #define _NGX_LOG_HPP 5 | 6 | //#include 7 | //#include 8 | //#include 9 | //#include 10 | 11 | #include "NgxWrapper.hpp" 12 | 13 | // for ngx_log_error 14 | template 15 | class NgxLog final : public NgxWrapper 16 | { 17 | public: 18 | typedef NgxWrapper super_type; 19 | typedef NgxLog this_type; 20 | public: 21 | NgxLog(ngx_log_t* l): super_type(l) 22 | {} 23 | 24 | NgxLog(ngx_log_t& l): super_type(l) 25 | {} 26 | 27 | ~NgxLog() = default; 28 | public: 29 | // check member log or connection with boost.tti 30 | BOOST_TTI_HAS_MEMBER_DATA(log) 31 | BOOST_TTI_HAS_MEMBER_DATA(connection) 32 | BOOST_TTI_MEMBER_TYPE(wrapped_type) 33 | 34 | // T has member log 35 | template 36 | NgxLog(T* x, 37 | typename boost::enable_if< 38 | has_member_data_log>::type* p = 0): 39 | NgxLog(x->log) 40 | {} 41 | 42 | // T has member connection but has not log 43 | // ngx_http_request_t/ngx_session_t 44 | template 45 | NgxLog(T* x, 46 | typename boost::enable_if< 47 | boost::mpl::and_< 48 | has_member_data_connection, 49 | boost::mpl::not_> 50 | > 51 | >::type* p = 0): 52 | NgxLog(x->connection) 53 | {} 54 | 55 | // T = NgxConnection/NgxRequest/NgxStreamSession/... 56 | template 57 | NgxLog(const T& x, 58 | typename boost::enable_if< 59 | boost::tti::valid_member_type< 60 | member_type_wrapped_type> 61 | >::type* p = 0): 62 | NgxLog(x.get()) 63 | {} 64 | 65 | //NgxLog(T* x) : super_type(x->log) {} 66 | //NgxLog(ngx_http_request_t* r): NgxLog(r->connection){} 67 | 68 | public: 69 | template 70 | void print(const char* fmt, const Args& ... args) const 71 | { 72 | ngx_log_error(level, get(), 0, fmt, args...); 73 | } 74 | 75 | template 76 | void print(ngx_err_t err, const Args& ... args) const 77 | { 78 | ngx_log_error(level, get(), err, args...); 79 | } 80 | }; 81 | 82 | typedef NgxLog NgxLogDebug; 83 | typedef NgxLog NgxLogInfo; 84 | typedef NgxLog NgxLogWarning; 85 | typedef NgxLog NgxLogError; 86 | typedef NgxLog NgxLogAlert; 87 | 88 | // for ngx_log_stderr 89 | class NgxStderrLog final 90 | { 91 | public: 92 | typedef NgxStderrLog this_type; 93 | public: 94 | NgxStderrLog() = default; 95 | ~NgxStderrLog() = default; 96 | public: 97 | template 98 | void print(const char* fmt, const Args& ... args) const 99 | { 100 | ngx_log_stderr(0, fmt, args...); 101 | } 102 | 103 | template 104 | void print(ngx_err_t err, const Args& ... args) const 105 | { 106 | ngx_log_stderr(err, args...); 107 | } 108 | }; 109 | 110 | #endif //_NGX_LOG_HPP 111 | -------------------------------------------------------------------------------- /ngxpp/NgxQueue.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_QUEUE_HPP 4 | #define _NGX_QUEUE_HPP 5 | 6 | //#include 7 | //#include 8 | //#include 9 | 10 | #include "NgxWrapper.hpp" 11 | 12 | // T must has a T::queue data member! 13 | template*q) 16 | > 17 | class NgxQueueNode final : public NgxWrapper 18 | { 19 | public: 20 | typedef NgxWrapper super_type; 21 | typedef NgxQueueNode this_type; 22 | 23 | //typedef ngx_queue_t T::*queue_ptr_type; 24 | public: 25 | NgxQueueNode(ngx_queue_t* ptr): super_type(ptr) 26 | {} 27 | 28 | NgxQueueNode(T& x): super_type(x.*q) 29 | {} 30 | 31 | NgxQueueNode(T* x): super_type(x->*q) 32 | {} 33 | 34 | ~NgxQueueNode() = default; 35 | public: 36 | NgxQueueNode next() const 37 | { 38 | return ngx_queue_next(get()); 39 | } 40 | 41 | NgxQueueNode prev() const 42 | { 43 | return ngx_queue_prev(get()); 44 | } 45 | public: 46 | void append(T& v) const 47 | { 48 | ngx_queue_insert_after(get(), &(v.*q)); 49 | } 50 | 51 | void remove() const 52 | { 53 | ngx_queue_remove(get()); 54 | } 55 | public: 56 | T& data() const 57 | { 58 | //reinterpret_cast(...) 59 | return *(T*)((u_char*)(get()) - offset); 60 | } 61 | }; 62 | 63 | // T = NgxQueueNode 64 | template 65 | class NgxQueueIterator final : 66 | public boost::iterator_facade< 67 | NgxQueueIterator, T, 68 | boost::bidirectional_traversal_tag> 69 | { 70 | public: 71 | typedef boost::iterator_facade< 72 | NgxQueueIterator, T, 73 | boost::bidirectional_traversal_tag> 74 | super_type; 75 | typedef NgxQueueIterator this_type; 76 | 77 | typedef typename super_type::reference reference; 78 | public: 79 | NgxQueueIterator(ngx_queue_t* p): m_cur(p) 80 | {} 81 | 82 | NgxQueueIterator() = default; 83 | ~NgxQueueIterator() = default; 84 | public: 85 | NgxQueueIterator(const this_type&) = default; 86 | NgxQueueIterator& operator=(const this_type&) = default; 87 | //public: 88 | // ngx_queue_t* get() const 89 | // { 90 | // return m_cur; 91 | // } 92 | 93 | private: 94 | friend class boost::iterator_core_access; 95 | 96 | reference dereference() const 97 | { 98 | m_proxy = m_cur; 99 | return m_proxy; 100 | } 101 | 102 | void increment() 103 | { 104 | m_cur = ngx_queue_next(m_cur); 105 | } 106 | 107 | void decrement() 108 | { 109 | m_cur = ngx_queue_prev(m_cur); 110 | } 111 | 112 | bool equal(this_type const& o) const 113 | { 114 | return m_cur == o.m_cur; 115 | } 116 | private: 117 | ngx_queue_t* m_cur = nullptr; 118 | mutable T m_proxy{m_cur}; 119 | }; 120 | 121 | // T must has a T::queue data member! 122 | template*q) 125 | > 126 | class NgxQueue final : public NgxWrapper 127 | { 128 | public: 129 | typedef NgxWrapper super_type; 130 | typedef NgxQueueNode node_type; 131 | typedef NgxQueue this_type; 132 | 133 | //typedef ngx_queue_t T::*queue_ptr_type; 134 | public: 135 | NgxQueue(ngx_queue_t& v): super_type(&v) 136 | {} 137 | 138 | NgxQueue(ngx_queue_t* ptr): super_type(ptr) 139 | {} 140 | 141 | NgxQueue(T& x): super_type(x.*q) 142 | {} 143 | 144 | NgxQueue(T* x): super_type(x->*q) 145 | {} 146 | 147 | ~NgxQueue() = default; 148 | public: 149 | void init() const 150 | { 151 | ngx_queue_init(get()); 152 | } 153 | 154 | bool empty() const 155 | { 156 | return ngx_queue_empty(get()); 157 | } 158 | 159 | public: 160 | //typedef node_type value_type; 161 | //typedef node_type& reference; 162 | typedef NgxQueueIterator iterator; 163 | typedef boost::reverse_iterator reverse_iterator; 164 | 165 | typedef const iterator const_iterator; 166 | typedef const reverse_iterator const_reverse_iterator; 167 | 168 | iterator begin() const 169 | { 170 | return iterator(ngx_queue_head(get())); 171 | } 172 | 173 | iterator end() const 174 | { 175 | return iterator(ngx_queue_sentinel(get())); 176 | } 177 | 178 | reverse_iterator rbegin() const 179 | { 180 | return reverse_iterator(end()); 181 | } 182 | 183 | reverse_iterator rend() const 184 | { 185 | return reverse_iterator(begin()); 186 | } 187 | public: 188 | node_type front() const 189 | { 190 | return ngx_queue_head(get()); 191 | //return *begin(); 192 | } 193 | 194 | node_type back() const 195 | { 196 | return ngx_queue_last(get()); 197 | //return *end(); 198 | } 199 | 200 | public: 201 | void insert(T& v) const 202 | { 203 | ngx_queue_insert_head(get(), &(v.*q)); 204 | } 205 | 206 | void append(T& v) const 207 | { 208 | ngx_queue_insert_tail(get(), &(v.*q)); 209 | } 210 | 211 | void insert(const iterator& iter, T& v) const 212 | { 213 | iter->append(v); 214 | //ngx_queue_insert_after(iter.get(), &(v.*q)); 215 | } 216 | public: 217 | void merge(ngx_queue_t* n) const 218 | { 219 | ngx_queue_add(get(), n); 220 | } 221 | 222 | template 223 | void sort(F f) const 224 | { 225 | BOOST_STATIC_ASSERT_MSG(boost::is_pointer::value, "not pointer"); 226 | 227 | ngx_queue_sort(get(), f); 228 | } 229 | }; 230 | 231 | #endif //_NGX_QUEUE_HPP 232 | -------------------------------------------------------------------------------- /ngxpp/NgxRbtree.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_RBTREE_HPP 4 | #define _NGX_RBTREE_HPP 5 | 6 | //#include 7 | 8 | //#include "Nginx.hpp" 9 | #include "NgxWrapper.hpp" 10 | 11 | template 15 | class NgxRbtree final : public NgxWrapper 16 | { 17 | public: 18 | typedef NgxWrapper super_type; 19 | typedef NgxRbtree this_type; 20 | 21 | typedef ngx_rbtree_key_t key_type; 22 | 23 | typedef ngx_rbtree_t tree_type; 24 | typedef ngx_rbtree_node_t node_type; 25 | public: 26 | NgxRbtree(tree_type* t) : super_type(t) 27 | {} 28 | 29 | NgxRbtree(tree_type& t) : super_type(&t) 30 | {} 31 | 32 | ~NgxRbtree() = default; 33 | public: 34 | static void init(tree_type& tree, node_type& s) 35 | { 36 | ngx_rbtree_init(&tree, &s, func); 37 | } 38 | public: 39 | bool empty() const 40 | { 41 | return get()->root == get()->sentinel; 42 | } 43 | 44 | key_type min_key() const 45 | { 46 | assert(!empty()); 47 | 48 | auto p = ngx_rbtree_min(get()->root, get()->sentinel); 49 | 50 | return p->key; 51 | } 52 | 53 | T& min() const 54 | { 55 | assert(!empty()); 56 | 57 | auto p = ngx_rbtree_min(get()->root, get()->sentinel); 58 | 59 | const auto offset = (std::size_t)&(((T*)0)->*np); 60 | 61 | return *(T*)((u_char*)(p) - offset); 62 | } 63 | public: 64 | void add(T& v) const 65 | { 66 | ngx_rbtree_insert(get(), &(v.*np)); 67 | } 68 | 69 | void del(T& v) const 70 | { 71 | ngx_rbtree_delete(get(), &(v.*np)); 72 | } 73 | public: 74 | typedef ngx_str_node_t str_node_type; 75 | 76 | // only valid with ngx_str_node_t! 77 | str_node_type* find(ngx_str_t* val, uint32_t hash) const 78 | { 79 | static_assert( 80 | std::is_same::value, 81 | "only ngx_str_node_t can find!"); 82 | 83 | return ngx_str_rbtree_lookup(get(), val, hash); 84 | } 85 | public: 86 | template 87 | void traverse(F f) const 88 | { 89 | do_traverse(get()->root, f); 90 | } 91 | private: 92 | template 93 | void do_traverse(node_type* p, F f) const 94 | { 95 | if(p == get()->sentinel) 96 | { 97 | return; 98 | } 99 | 100 | do_traverse(p->left, f); 101 | f(p); 102 | do_traverse(p->right, f); 103 | } 104 | }; 105 | 106 | template 107 | using NgxValueTree = NgxRbtree; 108 | 109 | template 110 | using NgxTimerTree = NgxRbtree; 111 | 112 | using NgxEventTimerTree = NgxTimerTree< 113 | ngx_event_t, &ngx_event_t::timer>; 114 | 115 | using NgxStringTree = NgxRbtree< 116 | ngx_str_node_t, &ngx_str_node_t::node, ngx_str_rbtree_insert_value>; 117 | 118 | 119 | #endif // _NGX_RBTREE_HPP 120 | -------------------------------------------------------------------------------- /ngxpp/NgxScript.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 2 | // Author: Chrono Law 3 | #ifndef _NGX_SCRIPT_HPP 4 | #define _NGX_SCRIPT_HPP 5 | 6 | #include "NgxException.hpp" 7 | #include "NgxValue.hpp" 8 | #include "NgxPool.hpp" 9 | 10 | inline namespace ngx_script_types { 11 | #ifdef ngx_http_variable 12 | 13 | typedef ngx_http_request_t ngx_script_ctx_t; 14 | 15 | typedef ngx_http_compile_complex_value_t ngx_compile_complex_value_t; 16 | typedef ngx_http_complex_value_t ngx_complex_value_t; 17 | 18 | static auto ngx_compile_complex_value = &ngx_http_compile_complex_value; 19 | static auto ngx_complex_value = &ngx_http_complex_value; 20 | 21 | #else //ngx_stream_variable 22 | 23 | typedef ngx_stream_session_t ngx_script_ctx_t; 24 | 25 | typedef ngx_stream_compile_complex_value_t ngx_compile_complex_value_t; 26 | typedef ngx_stream_complex_value_t ngx_complex_value_t; 27 | 28 | static auto ngx_compile_complex_value = &ngx_stream_compile_complex_value; 29 | static auto ngx_complex_value = &ngx_stream_complex_value; 30 | 31 | #endif 32 | } 33 | 34 | class NgxScript final 35 | { 36 | public: 37 | NgxScript() = default; 38 | ~NgxScript() = default; 39 | 40 | public: 41 | void init(ngx_conf_t* cf, ngx_str_t* source) 42 | { 43 | assert(source); 44 | 45 | m_source = *source; 46 | 47 | ngx_complex_value_t cv; 48 | ngx_compile_complex_value_t ccv; 49 | 50 | NgxValue::memzero(ccv); 51 | 52 | ccv.cf = cf; 53 | ccv.value = source; 54 | ccv.complex_value = &cv; 55 | 56 | auto rc = ngx_compile_complex_value(&ccv); 57 | 58 | NgxException::require(rc); 59 | 60 | if(!cv.lengths) // raw string 61 | { 62 | return; 63 | } 64 | 65 | m_cv = NgxPool(cf).alloc(); 66 | 67 | *m_cv = cv; 68 | } 69 | 70 | void init(ngx_conf_t* cf, ngx_str_t& source) 71 | { 72 | init(cf,&source); 73 | } 74 | public: 75 | ngx_str_t source() const 76 | { 77 | return m_source; 78 | } 79 | 80 | ngx_str_t str(ngx_script_ctx_t* r) const 81 | { 82 | if(!m_cv) // raw string 83 | { 84 | return m_source; 85 | } 86 | 87 | ngx_str_t value = ngx_null_string; 88 | 89 | auto rc = ngx_complex_value(r, m_cv, &value); 90 | 91 | NgxException::require(rc); 92 | 93 | return value; 94 | } 95 | private: 96 | ngx_str_t m_source = ngx_null_string; 97 | 98 | ngx_complex_value_t *m_cv = nullptr; 99 | }; 100 | 101 | #endif //_NGX_SCRIPT_HPP 102 | -------------------------------------------------------------------------------- /ngxpp/NgxStreamAll.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_STREAM_ALL_HPP 4 | #define _NGX_STREAM_ALL_HPP 5 | 6 | // nginx headers 7 | #include "NginxStream.hpp" 8 | 9 | // cpp headers 10 | #include "NgxCppInc.hpp" 11 | 12 | // core classes in namespace ngx{} 13 | #include "NgxCore.hpp" 14 | 15 | // namespace define 16 | #define NGX_STREAM_NAMESPACE_BEGIN namespace ngx { namespace stream { 17 | #define NGX_STREAM_NAMESPACE_END }} 18 | #define USING_STREAM_NAMESPACE using namespace ngx::stream; 19 | 20 | // stream classes 21 | NGX_STREAM_NAMESPACE_BEGIN 22 | 23 | #include "NgxModule.hpp" 24 | #include "NgxStreamModule.hpp" 25 | 26 | #include "NgxStreamSession.hpp" 27 | 28 | // nginx 1.11.2 support stream variables 29 | #if (nginx_version >= 1011002) 30 | #include "NgxVariable.hpp" 31 | #include "NgxComplexValue.hpp" 32 | #endif 33 | 34 | #if (nginx_version >= 1011005) 35 | #include "NgxStreamFilter.hpp" 36 | #endif //(nginx_version >= 1011005) 37 | 38 | //#include "NgxFactory.hpp" 39 | 40 | NGX_STREAM_NAMESPACE_END 41 | 42 | // open namespace ngx::stream 43 | USING_STREAM_NAMESPACE 44 | 45 | #endif // _NGX_STREAM_ALL_HPP 46 | 47 | -------------------------------------------------------------------------------- /ngxpp/NgxStreamFilter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_STREAM_FILTER_HPP 4 | #define _NGX_STREAM_FILTER_HPP 5 | 6 | // use Tag to instance static var 7 | template 8 | class NgxFilter final 9 | { 10 | public: 11 | typedef NgxFilter this_type; 12 | typedef ngx_stream_filter_pt stream_filter_ptr; 13 | 14 | NgxFilter() = default; 15 | ~NgxFilter() = default; 16 | 17 | public: 18 | static void init(stream_filter_ptr filter = nullptr) 19 | { 20 | if(filter) 21 | { 22 | set(ngx_stream_top_filter, filter); 23 | } 24 | } 25 | public: 26 | static ngx_int_t next(ngx_stream_session_t* s, 27 | ngx_chain_t *chain, ngx_uint_t from_upstream) 28 | { 29 | return next()(s, chain, from_upstream); 30 | } 31 | private: 32 | template 33 | static void set(T& top, T p) 34 | { 35 | next() = top; 36 | top = p; 37 | } 38 | 39 | template 40 | static T& next() 41 | { 42 | static T next_filter; 43 | 44 | return next_filter; 45 | } 46 | }; 47 | 48 | #endif //_NGX_STREAM_FILTER_HPP 49 | -------------------------------------------------------------------------------- /ngxpp/NgxStreamModule.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_STREAM_MODULE_HPP 4 | #define _NGX_STREAM_MODULE_HPP 5 | 6 | //#include 7 | //#include 8 | 9 | #include "NgxModule.hpp" 10 | 11 | class NgxStreamCoreModule final : 12 | public NgxModule 14 | { 15 | public: 16 | typedef NgxModule 18 | super_type; 19 | typedef NgxStreamCoreModule this_type; 20 | public: 21 | NgxStreamCoreModule() : super_type(ngx_stream_core_module) 22 | {} 23 | 24 | ~NgxStreamCoreModule() = default; 25 | public: 26 | // content handler 27 | template 28 | static void handler(ngx_conf_t* cf, F f) 29 | { 30 | instance().conf().srv(cf).handler = f; 31 | } 32 | 33 | public: 34 | #if (nginx_version < 1011005) 35 | static void access(ngx_conf_t* cf, ngx_stream_access_pt f) 36 | { 37 | instance().conf().main(cf).access_handler = f; 38 | } 39 | 40 | static void limit_conn(ngx_conf_t* cf, ngx_stream_access_pt f) 41 | { 42 | instance().conf().main(cf).limit_conn_handler = f; 43 | } 44 | #else // nginx 1.11.5 or later 45 | // phase handler 46 | template 47 | static void handler(ngx_conf_t* cf, F f, ngx_stream_phases p) 48 | { 49 | auto& c = instance().conf().main(cf); 50 | 51 | typedef NgxArray handler_array_t; 52 | 53 | assert(p <= NGX_STREAM_LOG_PHASE); 54 | handler_array_t arr(c.phases[p].handlers); 55 | arr.push(f); 56 | } 57 | #endif 58 | public: 59 | static this_type& instance() 60 | { 61 | static this_type m; 62 | return m; 63 | } 64 | }; 65 | 66 | #endif //_NGX_STREAM_MODULE_HPP 67 | -------------------------------------------------------------------------------- /ngxpp/NgxStreamSession.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 2 | // Author: Chrono Law 3 | #ifndef _NGX_STREAM_SESSION_HPP 4 | #define _NGX_STREAM_SESSION_HPP 5 | 6 | #include "NgxWrapper.hpp" 7 | 8 | class NgxStreamSession : public NgxWrapper 9 | { 10 | public: 11 | typedef NgxWrapper super_type; 12 | typedef NgxStreamSession this_type; 13 | public: 14 | NgxStreamSession(ngx_stream_session_t* s) : super_type(s) 15 | {} 16 | 17 | ~NgxStreamSession() = default; 18 | public: 19 | NgxStreamSession(ngx_connection_t* c) : 20 | NgxStreamSession(reinterpret_cast(c->data)) 21 | {} 22 | 23 | NgxStreamSession(ngx_event_t* ev) : 24 | NgxStreamSession(reinterpret_cast(ev->data)) 25 | {} 26 | 27 | public: 28 | ngx_connection_t* connection() const 29 | { 30 | return get()->connection; 31 | } 32 | public: 33 | #if nginx_version >= 1011005 34 | void send( ngx_chain_t *chain, ngx_uint_t from_upstream = true) const 35 | { 36 | auto rc = ngx_stream_top_filter(get(), chain, from_upstream); 37 | 38 | NgxException::fail(rc == NGX_ERROR); 39 | } 40 | #endif 41 | 42 | void close(ngx_uint_t rc = NGX_STREAM_OK) const 43 | { 44 | #if nginx_version >= 1011004 45 | ngx_stream_finalize_session(get(), rc); 46 | #else 47 | boost::ignore_unused(rc); 48 | ngx_stream_close_connection(connection()); 49 | #endif 50 | } 51 | }; 52 | 53 | #endif // _NGX_STREAM_SESSION_HPP 54 | -------------------------------------------------------------------------------- /ngxpp/NgxString.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_STRING_HPP 4 | #define _NGX_STRING_HPP 5 | 6 | //#include 7 | //#include 8 | //#include 9 | //#include 10 | //#include 11 | 12 | #include "NgxWrapper.hpp" 13 | 14 | // typed nginx string 15 | #define typed_ngx_string(str) ngx_str_t ngx_string(str) 16 | #define typed_ngx_null_string ngx_str_t ngx_null_string 17 | 18 | class NgxString final : public NgxWrapper 19 | { 20 | public: 21 | typedef NgxWrapper super_type; 22 | typedef NgxString this_type; 23 | 24 | typedef boost::string_ref string_ref_type; 25 | public: 26 | NgxString(ngx_str_t& str): 27 | super_type(str) 28 | {} 29 | 30 | // enable convert const object 31 | NgxString(const ngx_str_t& str): 32 | super_type(const_cast(str)) 33 | {} 34 | 35 | // disable temporary object 36 | NgxString(ngx_str_t&& str) = delete; 37 | 38 | ~NgxString() = default; 39 | public: 40 | const char* data() const 41 | { 42 | return reinterpret_cast(get()->data); 43 | } 44 | 45 | std::size_t size() const 46 | { 47 | return get()->len; 48 | } 49 | 50 | bool empty() const 51 | { 52 | return !get()->data || !get()->len; 53 | } 54 | 55 | string_ref_type str() const 56 | { 57 | return string_ref_type(data(), size()); 58 | } 59 | public: 60 | // nagetive means error 61 | operator ngx_int_t () const 62 | { 63 | return ngx_atoi(get()->data, get()->len); 64 | } 65 | public: 66 | // range concept 67 | typedef u_char char_type; 68 | typedef u_char* iterator; 69 | typedef iterator const_iterator; 70 | typedef boost::iterator_difference difference_type; 71 | public: 72 | const_iterator begin() const 73 | { 74 | return get()->data; 75 | } 76 | 77 | const_iterator end() const 78 | { 79 | return get()->data + get()->len; 80 | } 81 | 82 | public: 83 | const char_type& front() const 84 | { 85 | return *begin(); 86 | } 87 | const char_type& back() const 88 | { 89 | //return *std::prev(end()); 90 | return *boost::prior(end()); 91 | } 92 | public: 93 | bool contains(const this_type& x) const 94 | { 95 | return boost::contains(*this, x); 96 | } 97 | 98 | public: 99 | template 100 | friend T& operator<<(T& o, const this_type& s) 101 | { 102 | o.write(s.data(), s.size()); 103 | return o; 104 | } 105 | 106 | //template 107 | //friend T& operator<<(T& o, const ngx_str_t& s) 108 | //{ 109 | // o.write(reinterpret_cast(s.data), s.len); 110 | // return o; 111 | //} 112 | 113 | //template 114 | //friend T& operator<<(T& o, const volatile ngx_str_t& s) 115 | //{ 116 | // o.write(reinterpret_cast(s.data), s.len); 117 | // return o; 118 | //} 119 | 120 | friend bool operator==(const this_type& l, const this_type& r) 121 | { 122 | return l.size() == r.size() && 123 | ngx_strncmp(l.data(), r.data(), l.size()) == 0 124 | ; 125 | } 126 | public: 127 | template 128 | void printf(const Args& ... args) const 129 | { 130 | auto p = ngx_snprintf(get()->data, get()->len, args ...); 131 | get()->len = static_cast(p - get()->data); 132 | } 133 | }; 134 | 135 | // workaround for some compilers 136 | inline namespace ostream_for_ngx_str_t{ 137 | 138 | template 139 | T& operator<<(T& o, const ngx_str_t& s) 140 | { 141 | o.write(reinterpret_cast(s.data), s.len); 142 | return o; 143 | } 144 | 145 | template 146 | T& operator<<(T& o, const volatile ngx_str_t& s) 147 | { 148 | o.write(reinterpret_cast(s.data), s.len); 149 | return o; 150 | } 151 | 152 | } 153 | 154 | #endif //_NGX_STRING_HPP 155 | -------------------------------------------------------------------------------- /ngxpp/NgxSubRequest.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_HTTP_SUBREQUEST_HPP 4 | #define _NGX_HTTP_SUBREQUEST_HPP 5 | 6 | #include "NgxPool.hpp" 7 | 8 | #if nginx_version < 1013010 9 | #error "need latest nginx!" 10 | #endif 11 | 12 | template 13 | class NgxSubRequestHandler final 14 | { 15 | public: 16 | typedef NgxSubRequestHandler this_type; 17 | public: 18 | static ngx_int_t sub_post(ngx_http_request_t* r, void* data, ngx_int_t rc) 19 | try 20 | { 21 | r->parent->write_event_handler = ngx_http_core_run_phases; 22 | 23 | return T::sub_post(r, data, rc); 24 | } 25 | catch(const NgxException& e) 26 | { 27 | return e.code(); 28 | } 29 | }; 30 | 31 | template 32 | class NgxSubRequestHandler final 33 | { 34 | public: 35 | typedef NgxSubRequestHandler this_type; 36 | public: 37 | static ngx_int_t sub_post(ngx_http_request_t* r, void* data, ngx_int_t rc) 38 | try 39 | { 40 | r->parent->write_event_handler = &this_type::parent_post; 41 | 42 | return T::sub_post(r, data, rc); 43 | } 44 | catch(const NgxException& e) 45 | { 46 | return e.code(); 47 | } 48 | 49 | static void parent_post(ngx_http_request_t* r) 50 | try 51 | { 52 | ngx_http_finalize_request(r, T::parent_post(r)); 53 | } 54 | catch(...) 55 | { 56 | return; 57 | } 58 | }; 59 | 60 | template 61 | class NgxSubRequest final : public NgxWrapper 62 | { 63 | public: 64 | typedef NgxWrapper super_type; 65 | typedef NgxSubRequest this_type; 66 | typedef NgxSubRequestHandler this_handler; 67 | public: 68 | NgxSubRequest(ngx_http_request_t* r):super_type(r) 69 | {} 70 | ~NgxSubRequest() = default; 71 | public: 72 | ngx_http_request_t* create(ngx_str_t& uri, 73 | ngx_str_t& args, 74 | void* psr_data = nullptr, 75 | ngx_uint_t flags = NGX_HTTP_SUBREQUEST_IN_MEMORY) const 76 | { 77 | return create(&uri, &args, psr_data, flags); 78 | } 79 | 80 | ngx_http_request_t* create(ngx_str_t& uri, 81 | void* psr_data = nullptr, 82 | ngx_uint_t flags = NGX_HTTP_SUBREQUEST_IN_MEMORY) const 83 | { 84 | return create(&uri, nullptr, psr_data, flags); 85 | } 86 | public: 87 | ngx_http_request_t* create(ngx_str_t* uri, 88 | ngx_str_t* args, 89 | void* psr_data = nullptr, 90 | ngx_uint_t flags = 0) const 91 | { 92 | auto psr = NgxPool(get()).alloc(); 93 | 94 | psr->handler = &this_handler::sub_post; 95 | psr->data = psr_data; 96 | 97 | ngx_http_request_t* r = get(); 98 | ngx_http_request_t* sr; 99 | 100 | auto rc = ngx_http_subrequest(r, uri, args, &sr, psr, flags); 101 | NgxException::require(rc); // create failed throw exception 102 | 103 | // fix nginx's small bug 104 | if (r->headers_in.headers.last == &r->headers_in.headers.part) 105 | { 106 | sr->headers_in.headers.last = &sr->headers_in.headers.part; 107 | } 108 | 109 | if(copy_vars) //don't share vars with parent request 110 | { 111 | copy_variables(sr); 112 | } 113 | 114 | return sr; 115 | } 116 | private: 117 | void copy_variables(ngx_http_request_t* sr) const 118 | { 119 | ngx_http_request_t* r = get(); 120 | 121 | auto& cmcf = NgxHttpCoreModule::instance().conf().main(r); 122 | 123 | auto size = sizeof(ngx_http_variable_value_t) * cmcf.variables.nelts; 124 | 125 | sr->variables = NgxPool(sr).nalloc(size); 126 | 127 | ngx_memcpy(sr->variables, r->variables, size); 128 | } 129 | }; 130 | 131 | #endif //_NGX_HTTP_SUBREQUEST_HPP 132 | -------------------------------------------------------------------------------- /ngxpp/NgxThread.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_THREAD_HPP 4 | #define _NGX_THREAD_HPP 5 | 6 | #include "NgxPool.hpp" 7 | #include "NgxEvent.hpp" 8 | 9 | template 10 | class NgxThreadTask final : public NgxWrapper 11 | { 12 | public: 13 | typedef NgxWrapper super_type; 14 | typedef NgxThreadTask this_type; 15 | typedef T task_ctx_type; 16 | public: 17 | NgxThreadTask(ngx_thread_task_t* t) : super_type(t) 18 | {} 19 | 20 | ~NgxThreadTask() = default; 21 | public: 22 | T* ctx() const 23 | { 24 | return reinterpret_cast(get()->ctx); 25 | } 26 | 27 | template 28 | void handler(F f) const 29 | { 30 | if(!get()->handler) 31 | { 32 | get()->handler = f; 33 | } 34 | } 35 | public: 36 | NgxEvent event() const 37 | { 38 | return &get()->event; 39 | } 40 | public: 41 | static ngx_thread_task_t* create(const NgxPool& pool) 42 | { 43 | auto p = pool.thread_task(); 44 | 45 | return p; 46 | } 47 | }; 48 | 49 | class NgxThreadPool final : public NgxWrapper 50 | { 51 | public: 52 | typedef NgxWrapper super_type; 53 | typedef NgxThreadPool this_type; 54 | public: 55 | NgxThreadPool(ngx_thread_pool_t* p) : super_type(p) 56 | {} 57 | 58 | NgxThreadPool(ngx_str_t name) : super_type(acquire(name)) 59 | {} 60 | 61 | ~NgxThreadPool() = default; 62 | public: 63 | void post(ngx_thread_task_t* task) const 64 | { 65 | auto rc = ngx_thread_task_post(get(), task); 66 | 67 | NgxException::require(rc); 68 | } 69 | public: 70 | static ngx_thread_pool_t* acquire(ngx_str_t& name) 71 | { 72 | auto p = ngx_thread_pool_get((ngx_cycle_t *) ngx_cycle, &name); 73 | 74 | NgxException::require(p); 75 | 76 | return p; 77 | } 78 | }; 79 | 80 | #endif //_NGX_THREAD_HPP 81 | -------------------------------------------------------------------------------- /ngxpp/NgxTimer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_TIMER_HPP 4 | #define _NGX_TIMER_HPP 5 | 6 | //#include 7 | //#include 8 | //#include 9 | 10 | #include "NgxValue.hpp" 11 | 12 | template 13 | class NgxTimerEv final 14 | { 15 | public: 16 | typedef NgxTimerEv this_type; 17 | typedef T factory_type; 18 | public: 19 | NgxTimerEv() = default; 20 | ~NgxTimerEv() = default; 21 | public: 22 | typedef boost::function func_type; 23 | public: 24 | // f can be bind or lambda 25 | void init(func_type f, ngx_msec_t ms = ngx_nil) 26 | { 27 | m_func = f; 28 | 29 | NgxValue::memzero(m_ev); 30 | 31 | m_ev.handler = &T::call; 32 | m_ev.data = this; 33 | m_ev.log = ngx_cycle->log; 34 | 35 | if(NgxValue::invalid(ms)) 36 | { 37 | return; 38 | } 39 | 40 | start(ms); 41 | } 42 | 43 | void start(ngx_msec_t ms) 44 | { 45 | ngx_add_timer(&m_ev, ms); 46 | } 47 | 48 | public: 49 | // deprecated 50 | ngx_int_t init(ngx_msec_t ms, func_type f) 51 | { 52 | init(f, ms); 53 | return NGX_OK; 54 | } 55 | public: 56 | void clear() 57 | { 58 | //m_ev.timedout = false; 59 | 60 | if(m_ev.timer_set) 61 | { 62 | ngx_del_timer(&m_ev); 63 | } 64 | } 65 | public: 66 | //void cleanup(ngx_http_request_t* r) const 67 | //{ 68 | // auto cln = ngx_http_cleanup_add(r, 0); 69 | 70 | // NgxException::require(cln); 71 | 72 | // cln->handler = &this_type::cleanup_handler; 73 | // cln->data = this; 74 | //} 75 | 76 | public: 77 | void operator()() const 78 | { 79 | if(!m_ev.timedout) // not timedout, do not call func 80 | { 81 | return; 82 | } 83 | 84 | m_func(); 85 | } 86 | private: 87 | ngx_event_t m_ev; 88 | func_type m_func; 89 | }; 90 | 91 | class NgxTimer final 92 | { 93 | public: 94 | typedef NgxTimerEv timer_event_type; 95 | typedef timer_event_type::func_type func_type; 96 | public: 97 | NgxTimer() = default; 98 | ~NgxTimer() = default; 99 | public: 100 | static ngx_int_t add(ngx_msec_t ms, func_type f) 101 | { 102 | return acquire().init(ms, f); 103 | } 104 | 105 | public: 106 | static void call(ngx_event_t *ev) 107 | { 108 | auto& e = *reinterpret_cast(ev->data); 109 | 110 | e(); 111 | 112 | //e.clear(); 113 | 114 | release(e); 115 | } 116 | private: 117 | typedef std::deque timer_pool_type; 118 | 119 | static timer_pool_type& pool() 120 | { 121 | static timer_pool_type p; 122 | return p; 123 | } 124 | 125 | private: 126 | static timer_event_type& acquire() 127 | { 128 | if(pool().empty()) 129 | { 130 | return *boost::factory()(); 131 | } 132 | 133 | auto p = pool().front(); 134 | pool().pop_front(); 135 | 136 | return *p; 137 | } 138 | 139 | static void release(timer_event_type& e) 140 | { 141 | pool().push_back(&e); 142 | } 143 | }; 144 | 145 | class NgxTimerCaller final 146 | { 147 | public: 148 | typedef NgxTimerEv timer_event_type; 149 | typedef timer_event_type::func_type func_type; 150 | public: 151 | static void call(ngx_event_t *ev) 152 | { 153 | auto& e = *reinterpret_cast(ev->data); 154 | 155 | e(); 156 | } 157 | }; 158 | 159 | typedef NgxTimerCaller::timer_event_type NgxTimerEvent; 160 | 161 | #endif //_NGX_TIMER_HPP 162 | 163 | -------------------------------------------------------------------------------- /ngxpp/NgxUpstream.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_HTTP_UPSTREAM_HPP 4 | #define _NGX_HTTP_UPSTREAM_HPP 5 | 6 | #include "NgxException.hpp" 7 | #include "NgxLog.hpp" 8 | #include "NgxBuf.hpp" 9 | 10 | class NgxUpstream final : public NgxWrapper 11 | { 12 | public: 13 | typedef NgxWrapper super_type; 14 | typedef NgxUpstream this_type; 15 | public: 16 | NgxUpstream(ngx_http_upstream_t* u) 17 | :super_type(u) 18 | {} 19 | 20 | NgxUpstream(ngx_http_request_t* r): 21 | super_type(r->upstream) 22 | {} 23 | 24 | ~NgxUpstream() = default; 25 | public: 26 | void conf(ngx_http_upstream_conf_t& cf) const 27 | { 28 | get()->conf = &cf; 29 | get()->buffering = cf.buffering; 30 | } 31 | 32 | void buffering(bool flag) const 33 | { 34 | get()->buffering = flag; 35 | } 36 | 37 | void request(ngx_chain_t* bufs) const 38 | { 39 | if(!get()->request_bufs) 40 | { 41 | get()->request_bufs = bufs; 42 | return; 43 | } 44 | 45 | NgxChain ch = get()->request_bufs; 46 | ch.append(bufs); 47 | } 48 | 49 | ngx_buf_t* buffer() const 50 | { 51 | return &get()->buffer; 52 | } 53 | public: 54 | ngx_http_upstream_headers_in_t& headers() const 55 | { 56 | return get()->headers_in; 57 | } 58 | 59 | ngx_http_upstream_state_t& state() const 60 | { 61 | return *get()->state; 62 | } 63 | }; 64 | 65 | template< 66 | ngx_int_t(*create_request)(ngx_http_request_t*) = nullptr, 67 | ngx_int_t(*reinit_request)(ngx_http_request_t *r) = nullptr, 68 | ngx_int_t(*process_header)(ngx_http_request_t*) = nullptr, 69 | void(*finalize_request)(ngx_http_request_t*,ngx_int_t) = nullptr 70 | > 71 | class NgxUpstreamHelper final : public NgxWrapper 72 | { 73 | public: 74 | typedef NgxWrapper super_type; 75 | typedef NgxUpstreamHelper this_type; 76 | typedef NgxUpstream upstream_type; 77 | public: 78 | NgxUpstreamHelper(ngx_http_request_t* r): 79 | super_type(r), m_upstream(create()) 80 | {} 81 | 82 | ~NgxUpstreamHelper() = default; 83 | public: 84 | void conf(ngx_http_upstream_conf_t& cf) const 85 | { 86 | upstream().conf(cf); 87 | } 88 | 89 | ngx_int_t start(bool read_body = false) const 90 | { 91 | // set callback 92 | if(!upstream()->create_request) 93 | { 94 | upstream()->create_request = create_request; 95 | upstream()->reinit_request = reinit_request; 96 | upstream()->process_header = process_header; 97 | upstream()->finalize_request = finalize_request; 98 | } 99 | 100 | // check callback function 101 | assert(upstream()->create_request); 102 | 103 | //if(!upstream()->reinit_request) 104 | //{ 105 | // upstream()->reinit_request = &this_type::default_reinit_request; 106 | //} 107 | 108 | if(!upstream()->finalize_request) 109 | { 110 | upstream()->finalize_request = &this_type::default_finalize_request; 111 | } 112 | 113 | // init upstream 114 | if(read_body) 115 | { 116 | auto rc = 117 | ngx_http_read_client_request_body(get(), ngx_http_upstream_init); 118 | 119 | NgxException::fail(rc >= NGX_HTTP_SPECIAL_RESPONSE); 120 | } 121 | else 122 | { 123 | auto rc = ngx_http_discard_request_body(get()); 124 | NgxException::require(rc); 125 | 126 | ++get()->main->count; 127 | ngx_http_upstream_init(get()); 128 | } 129 | 130 | return NGX_DONE; 131 | } 132 | public: 133 | const upstream_type& upstream() const 134 | { 135 | return m_upstream; 136 | } 137 | 138 | private: 139 | upstream_type m_upstream; 140 | private: 141 | ngx_http_upstream_t* create() const 142 | { 143 | if(!get()->upstream) 144 | { 145 | auto rc = ngx_http_upstream_create(get()); 146 | 147 | NgxException::require( 148 | rc == NGX_OK, NGX_HTTP_INTERNAL_SERVER_ERROR); 149 | } 150 | 151 | return get()->upstream; 152 | } 153 | private: 154 | static void default_finalize_request(ngx_http_request_t* r,ngx_int_t rc) 155 | { 156 | NgxLogDebug(r).print("default_finalize_request"); 157 | } 158 | //static ngx_int_t default_reinit_request(ngx_http_request_t* r) 159 | //{ 160 | // NgxLogDebug(r).print("default_reinit_request"); 161 | // return NGX_OK; 162 | //} 163 | }; 164 | 165 | #endif //_NGX_HTTP_UPSTREAM_HPP 166 | -------------------------------------------------------------------------------- /ngxpp/NgxValue.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_VALUE_HPP 4 | #define _NGX_VALUE_HPP 5 | 6 | //#include "Nginx.hpp" 7 | 8 | // NGX_CONF_UNSET = -1 9 | class NgxUnsetValue final 10 | { 11 | public: 12 | template 13 | operator T () const 14 | { 15 | return static_cast(-1); 16 | } 17 | 18 | template 19 | operator T* () const 20 | { 21 | return reinterpret_cast(-1); 22 | } 23 | public: 24 | static const NgxUnsetValue& get() 25 | { 26 | static NgxUnsetValue const v = {}; 27 | return v; 28 | } 29 | }; 30 | 31 | class NgxValue final 32 | { 33 | public: 34 | NgxValue() = default; 35 | ~NgxValue() = default; 36 | public: 37 | template 38 | static void unset(T& v, Args& ... args) 39 | { 40 | v = NgxUnsetValue::get(); 41 | unset(args...); 42 | } 43 | 44 | static void unset() {} 45 | 46 | public: 47 | template 48 | static bool invalid(const T& v) 49 | { 50 | return v == static_cast(NgxUnsetValue::get()); 51 | } 52 | 53 | template 54 | static void init(T& x, const U& v) 55 | { 56 | if (invalid(x)) 57 | { 58 | x = v; 59 | } 60 | } 61 | public: 62 | template 63 | static void memzero(T& v, std::size_t n = sizeof(T)) 64 | { 65 | ngx_memzero(&v, n); 66 | } 67 | 68 | template 69 | static void memzero(T* v, std::size_t n = sizeof(T)) 70 | { 71 | ngx_memzero(v, n); 72 | } 73 | 74 | public: 75 | template 76 | static void merge(T& c, const U& p, const V& d) 77 | { 78 | if (invalid(c)) 79 | { 80 | c = invalid(p) ? d : p; 81 | } 82 | } 83 | 84 | public: 85 | static bool invalid(const ngx_str_t& v) 86 | { 87 | return !v.data || !v.len; 88 | } 89 | 90 | //static void merge(ngx_str_t& c, const ngx_str_t& p, const ngx_str_t& d) 91 | //{ 92 | // if(!c.data) 93 | // { 94 | // c = p.data ? p : d; 95 | // } 96 | //} 97 | }; 98 | 99 | // a convenient var for unset 100 | namespace { 101 | auto&& ngx_nil = NgxUnsetValue::get(); 102 | } 103 | 104 | // convenient compare 105 | 106 | template 107 | bool operator==(const T& x, const NgxUnsetValue&) 108 | { 109 | return NgxValue::invalid(x); 110 | } 111 | 112 | template 113 | bool operator!=(const T& x, const NgxUnsetValue&) 114 | { 115 | return !NgxValue::invalid(x); 116 | } 117 | 118 | #endif //_NGX_VALUE_HPP 119 | -------------------------------------------------------------------------------- /ngxpp/NgxVariable.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_VAR_HPP 4 | #define _NGX_VAR_HPP 5 | 6 | //#include 7 | //#include 8 | 9 | #include "NgxString.hpp" 10 | #include "NgxException.hpp" 11 | 12 | class NgxVariableValue final : public NgxWrapper 13 | { 14 | public: 15 | typedef NgxWrapper super_type; 16 | typedef NgxVariableValue this_type; 17 | public: 18 | NgxVariableValue(ngx_variable_value_t* v): 19 | super_type(v) 20 | {} 21 | 22 | NgxVariableValue(ngx_variable_value_t& v): 23 | super_type(v) 24 | {} 25 | 26 | ~NgxVariableValue() = default; 27 | public: 28 | void set(ngx_str_t& str, bool clear = false) 29 | { 30 | set(&str, clear); 31 | } 32 | 33 | void set(ngx_str_t* str, bool clear = false) 34 | { 35 | get()->len = clear ? 0 : str->len; 36 | get()->data = clear ? nullptr : str->data; 37 | 38 | get()->valid = !clear; 39 | get()->not_found = clear; 40 | get()->no_cacheable = false; 41 | } 42 | public: 43 | bool valid() const 44 | { 45 | return get() && get()->valid && !get()->not_found; 46 | } 47 | 48 | ngx_str_t str() const 49 | { 50 | return valid()? 51 | ngx_str_t{get()->len, get()->data}: 52 | ngx_str_t ngx_null_string; 53 | } 54 | }; 55 | 56 | inline namespace ngx_variable_types { 57 | #ifndef ngx_stream_cpp_version //ngx_http_variable 58 | 59 | #define NGX_VAR_CHANGEABLE NGX_HTTP_VAR_CHANGEABLE 60 | #define NGX_VAR_INDEXED NGX_HTTP_VAR_INDEXED 61 | 62 | using NgxCtxCoreModule = NgxHttpCoreModule; 63 | 64 | using ngx_variable_ctx_t = ngx_http_request_t; 65 | using ngx_variable_t = ngx_http_variable_t; 66 | using ngx_set_variable_pt = ngx_http_set_variable_pt; 67 | using ngx_get_variable_pt = ngx_http_get_variable_pt; 68 | 69 | static auto ngx_add_variable = &ngx_http_add_variable; 70 | static auto ngx_get_variable = &ngx_http_get_variable; 71 | 72 | #else //ngx_stream_variable 73 | 74 | using NgxCtxCoreModule = NgxStreamCoreModule; 75 | 76 | #define NGX_VAR_CHANGEABLE NGX_STREAM_VAR_CHANGEABLE 77 | #define NGX_VAR_INDEXED NGX_STREAM_VAR_INDEXED 78 | 79 | using ngx_variable_ctx_t = ngx_stream_session_t; 80 | using ngx_variable_t = ngx_stream_variable_t; 81 | using ngx_set_variable_pt = ngx_stream_set_variable_pt; 82 | using ngx_get_variable_pt = ngx_stream_get_variable_pt; 83 | 84 | static auto ngx_add_variable = &ngx_stream_add_variable; 85 | static auto ngx_get_variable = &ngx_stream_get_variable; 86 | 87 | #endif 88 | } 89 | 90 | class NgxVariable final 91 | { 92 | public: 93 | typedef NgxVariable this_type; 94 | typedef boost::string_ref string_ref_type; 95 | public: 96 | NgxVariable(ngx_variable_ctx_t* r, string_ref_type name): 97 | m_r(r), m_pool(r) 98 | { 99 | m_name = m_pool.dup(name); 100 | m_key = ngx_hash_strlow(m_name.data, m_name.data, m_name.len); 101 | } 102 | 103 | ~NgxVariable() = default; 104 | public: 105 | ngx_str_t get() const 106 | { 107 | NgxVariableValue vv = ngx_get_variable(m_r, 108 | const_cast(&m_name), m_key); 109 | 110 | return vv.str(); 111 | } 112 | 113 | bool set(string_ref_type value) const 114 | { 115 | auto& cmcf = NgxCtxCoreModule::instance().conf().main(m_r); 116 | 117 | // p = void* 118 | auto p = ngx_hash_find(&cmcf.variables_hash, 119 | m_key, m_name.data, m_name.len); 120 | 121 | // not found 122 | if(!p) 123 | { 124 | return false; 125 | } 126 | 127 | auto v = reinterpret_cast(p); 128 | 129 | // not changeable 130 | if(!(v->flags & NGX_VAR_CHANGEABLE)) 131 | { 132 | return false; 133 | } 134 | 135 | auto val = m_pool.dup(value); 136 | 137 | NgxVariableValue vv = v->set_handler ? 138 | m_pool.alloc(): 139 | // no set handler but indexed in request 140 | ((v->flags & NGX_VAR_INDEXED)? 141 | &m_r->variables[v->index] : nullptr); 142 | 143 | if(!vv) 144 | { 145 | return false; 146 | } 147 | 148 | vv.set(val, value.empty()); 149 | 150 | if(v->set_handler) 151 | { 152 | v->set_handler(m_r, vv, v->data); 153 | } 154 | 155 | return true; 156 | } 157 | public: 158 | operator ngx_str_t() const 159 | { 160 | return get(); 161 | } 162 | 163 | void operator=(string_ref_type value) const 164 | { 165 | set(value); 166 | } 167 | public: 168 | template 169 | friend T& operator<<(T& o, const this_type& x) 170 | { 171 | //o << x.get(); // non-deducible context error 172 | 173 | auto s = x.get(); 174 | o.write(reinterpret_cast(s.data), s.len); 175 | return o; 176 | } 177 | private: 178 | ngx_variable_ctx_t* m_r = nullptr; 179 | NgxPool m_pool; 180 | ngx_str_t m_name = ngx_null_string; 181 | ngx_uint_t m_key = 0; 182 | }; 183 | 184 | class NgxVarManager final 185 | { 186 | public: 187 | typedef NgxVarManager this_type; 188 | typedef boost::string_ref string_ref_type; 189 | public: 190 | NgxVarManager(ngx_variable_ctx_t* r): m_r(r) 191 | {} 192 | ~NgxVarManager() = default; 193 | public: 194 | NgxVariable operator[](string_ref_type name) const 195 | { 196 | return NgxVariable(m_r, name); 197 | } 198 | private: 199 | ngx_variable_ctx_t* m_r = nullptr; 200 | }; 201 | 202 | template 203 | class NgxVariables final 204 | { 205 | public: 206 | typedef NgxVariables this_type; 207 | typedef ngx_variable_t var_type; 208 | public: 209 | static ngx_int_t init(ngx_conf_t *cf) 210 | { 211 | if(!get_vars) 212 | { 213 | return NGX_OK; 214 | } 215 | 216 | for (auto v = get_vars(); v->name.len; ++v) 217 | { 218 | auto var = ngx_add_variable(cf, &v->name, v->flags); 219 | 220 | NgxException::fail(!var); 221 | 222 | var->get_handler = v->get_handler; 223 | var->data = reinterpret_cast(v->data); 224 | } 225 | 226 | return NGX_OK; 227 | } 228 | public: 229 | static var_type* create(ngx_conf_t *cf, ngx_str_t& name, ngx_uint_t flags = 0) 230 | { 231 | auto p = ngx_add_variable(cf, &name, flags); 232 | 233 | NgxException::require(p); 234 | 235 | return p; 236 | } 237 | }; 238 | 239 | #endif //_NGX_VAR_HPP 240 | 241 | -------------------------------------------------------------------------------- /ngxpp/NgxWrapper.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2017 2 | // Author: Chrono Law 3 | #ifndef _NGX_WRAPPER_HPP 4 | #define _NGX_WRAPPER_HPP 5 | 6 | //#include 7 | 8 | //#include "Nginx.hpp" 9 | 10 | // T = ngx_list_t, ngx_array_t, ngx_pool_t, ... 11 | template 12 | class NgxWrapper 13 | { 14 | public: 15 | typedef typename ::boost::remove_pointer::type wrapped_type; 16 | 17 | typedef wrapped_type* pointer_type; 18 | typedef wrapped_type& reference_type; 19 | private: 20 | pointer_type m_ptr = nullptr; 21 | protected: 22 | NgxWrapper(pointer_type p):m_ptr(p) 23 | { 24 | //assert(p); 25 | } 26 | 27 | NgxWrapper(reference_type x):m_ptr(&x) 28 | {} 29 | 30 | ~NgxWrapper() = default; 31 | 32 | public: 33 | pointer_type get() const 34 | { 35 | return m_ptr; 36 | } 37 | 38 | operator pointer_type () const 39 | { 40 | return get(); 41 | } 42 | 43 | pointer_type operator->() const 44 | { 45 | return get(); 46 | } 47 | public: 48 | operator bool () const 49 | { 50 | return get(); 51 | } 52 | //public: 53 | // operator reference_type () const 54 | // { 55 | // return *get(); 56 | // } 57 | }; 58 | 59 | #endif //_NGX_WRAPPER_HPP 60 | -------------------------------------------------------------------------------- /ngxpp/config: -------------------------------------------------------------------------------- 1 | #./configure --add-module=$HOME/ngx_cpp_dev/ngxpp 2 | 3 | # cpp module name 4 | ngx_addon_name=ngx_cpp_module 5 | 6 | # http modules 7 | HTTP_INCS="$HTTP_INCS $ngx_addon_dir" 8 | 9 | # stream modules 10 | #if [ $STREAM != NO ]; then 11 | # STREAM_INCS="$STREAM_INCS $ngx_addon_dir" 12 | #fi 13 | 14 | #CORE_LIBS="$CORE_LIBS -static-libgcc -static-libstdc++" 15 | 16 | -------------------------------------------------------------------------------- /patch/auto/make.patch: -------------------------------------------------------------------------------- 1 | --- make.orig 2016-12-13 23:21:24.000000000 +0800 2 | +++ make 2016-12-19 13:13:02.556939026 +0800 3 | @@ -23,7 +23,10 @@ 4 | CC = $CC 5 | CFLAGS = $CFLAGS 6 | CPP = $CPP 7 | -LINK = $LINK 8 | +#LINK = $LINK 9 | + 10 | +CXXFLAGS = -g -O0 -std=c++11 -Wall 11 | +LINK = g++ 12 | 13 | END 14 | 15 | @@ -425,10 +428,16 @@ 16 | 17 | ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"` 18 | 19 | + ext=${ngx_src##*.} 20 | + ngx_cxx=$ngx_cc 21 | + if [ $ext = "cpp" ]; then 22 | + ngx_cxx="$ngx_cc \$(CXXFLAGS)" 23 | + fi 24 | + 25 | cat << END >> $NGX_MAKEFILE 26 | 27 | $ngx_obj: \$(ADDON_DEPS)$ngx_cont$ngx_src 28 | - $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX 29 | + $ngx_cxx$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX 30 | 31 | END 32 | done 33 | @@ -660,10 +669,16 @@ 34 | END 35 | else 36 | 37 | + ext=${ngx_source##*.} 38 | + ngx_cxx=$ngx_cc 39 | + if [ $ext = "cpp" ]; then 40 | + ngx_cxx="$ngx_cc \$(CXXFLAGS)" 41 | + fi 42 | + 43 | cat << END >> $NGX_MAKEFILE 44 | 45 | $ngx_obj: \$(ADDON_DEPS)$ngx_cont$ngx_src 46 | - $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX 47 | + $ngx_cxx$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX 48 | 49 | END 50 | 51 | -------------------------------------------------------------------------------- /setup/boost.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | wget -O boost.tar.gz http://downloads.sourceforge.net/project/boost/boost/1.59.0/boost_1_59_0.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fboost%2Ffiles%2Fboost%2F1.59.0%2F&ts=1447386812&use_mirror=jaist 3 | 4 | tar xvfz boost.tar.gz 5 | 6 | cd boost_1_59_0 7 | 8 | ./bootstrap.sh 9 | 10 | sudo ./b2 link=static install 11 | 12 | -------------------------------------------------------------------------------- /setup/centos_gcc.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | GCC_V='4.8.5' 4 | sudo yum install -y glibc-static libstdc++-static 5 | 6 | wget http://ftp.gnu.org/gnu/gcc/gcc-${GCC_V}/gcc-${GCC_V}.tar.gz -O gcc-${GCC_V}.tar.gz 7 | 8 | tar xzf gcc-${GCC_V}.tar.gz 9 | cd gcc-${GCC_V} 10 | ./contrib/download_prerequisites 11 | 12 | cd .. 13 | mkdir build_gcc${GCC_V} 14 | cd build_gcc${GCC_V} 15 | ../gcc-${GCC_V}/configure --prefix=/usr/ --enable-checking=release --enable-languages=c,c++ --disable-multilib 16 | 17 | make -j23 18 | sudo make install 19 | 20 | cd .. 21 | 22 | rm -rf build_gcc${GCC_V} gcc-${GCC_V} gcc-${GCC_V}.tar.gz 23 | -------------------------------------------------------------------------------- /setup/github.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # download openresty resources 3 | 4 | github="~/github" 5 | 6 | mkdir ${github} 7 | cd ${github} 8 | 9 | git clone git@github.com:simpl/ngx_devel_kit.git 10 | git clone git@github.com:openresty/lua-nginx-module.git 11 | git clone git@github.com:openresty/stream-lua-nginx-module.git 12 | 13 | cd - 14 | 15 | -------------------------------------------------------------------------------- /setup/jemalloc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ver="4.2.1" 3 | 4 | wget https://github.com/jemalloc/jemalloc/archive/${ver}.tar.gz -O jemalloc.tar.gz 5 | 6 | tar xvfz jemalloc.tar.gz 7 | 8 | cd jemalloc-${ver} 9 | 10 | # we must have installed autoconf 11 | 12 | ./autogen.sh 13 | 14 | make dist 15 | make 16 | 17 | sudo make install 18 | 19 | -------------------------------------------------------------------------------- /stream/discard/ModNdgStreamDiscard.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016-2017 2 | // Author: Chrono Law 3 | #include "NdgStreamDiscardInit.hpp" 4 | 5 | auto ndg_stream_discard_module = NdgStreamDiscardInit::module(); 6 | -------------------------------------------------------------------------------- /stream/discard/NdgStreamDiscardConf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_STREAM_DISCARD_CONF_HPP 4 | #define _NDG_STREAM_DISCARD_CONF_HPP 5 | 6 | #include "NgxStreamAll.hpp" 7 | 8 | class NdgStreamDiscardConf final 9 | { 10 | public: 11 | typedef NdgStreamDiscardConf this_type; 12 | public: 13 | NdgStreamDiscardConf() = default; 14 | ~NdgStreamDiscardConf() = default; 15 | public: 16 | ngx_msec_t timeout = ngx_nil; 17 | public: 18 | static void* create(ngx_conf_t* cf) 19 | { 20 | return NgxPool(cf).alloc(); 21 | } 22 | 23 | static char* merge(ngx_conf_t *cf, void *parent, void *child) 24 | { 25 | boost::ignore_unused(cf); 26 | 27 | auto& prev = cast(parent); 28 | auto& conf = cast(child); 29 | 30 | NgxValue::merge(conf.timeout, prev.timeout, 5000); 31 | 32 | return NGX_CONF_OK; 33 | } 34 | public: 35 | static this_type& cast(void* p) 36 | { 37 | return *reinterpret_cast(p); 38 | } 39 | }; 40 | 41 | NGX_MOD_INSTANCE(NdgStreamDiscardModule, 42 | ndg_stream_discard_module, NdgStreamDiscardConf) 43 | 44 | #endif //_NDG_STREAM_DISCARD_CONF_HPP 45 | -------------------------------------------------------------------------------- /stream/discard/NdgStreamDiscardHandler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_STREAM_DISCARD_HANDLER_HPP 4 | #define _NDG_STREAM_DISCARD_HANDLER_HPP 5 | 6 | #include 7 | 8 | #include "NdgStreamDiscardConf.hpp" 9 | 10 | class NdgStreamDiscardHandler final 11 | { 12 | public: 13 | typedef NdgStreamDiscardHandler this_type; 14 | typedef NdgStreamDiscardModule this_module; 15 | public: 16 | static void handler(ngx_stream_session_t *s) 17 | try 18 | { 19 | NgxConnection conn(s); 20 | 21 | NgxWriteEvent wev = conn.write_event(); 22 | //wev.handler(&this_type::block_write_handler); 23 | wev.handler([](ngx_event_t *ev){}); 24 | 25 | NgxReadEvent rev = conn.read_event(); 26 | 27 | rev.handler(&this_type::discard_read_handler); 28 | 29 | rev.process(); 30 | } 31 | catch(const NgxException& e) 32 | { 33 | NgxLogError(s).print("error = %d", e.code()); 34 | NgxStreamSession(s).close(); 35 | } 36 | private: 37 | static void discard_read_handler(ngx_event_t *ev) 38 | try 39 | { 40 | NgxReadEvent rev(ev); 41 | NgxConnection conn(ev); 42 | 43 | // check timedout and error 44 | NgxException::fail(rev.expired(), NGX_ETIMEDOUT); 45 | NgxException::fail(conn.closed()); 46 | 47 | if(rev.ready()) 48 | { 49 | // read from client 50 | std::array buf; 51 | NgxLogError log(conn); 52 | 53 | ssize_t n = 0; 54 | 55 | // read until can not read 56 | for(;;) 57 | { 58 | n = conn.recv(buf.data(), buf.size()); 59 | 60 | if(n <= 0) // error accured 61 | { 62 | break; 63 | } 64 | 65 | log.print("recv %d bytes", n); 66 | 67 | conn.reusable(false); 68 | } // end for 69 | 70 | //NgxException::fail(n == NGX_ERROR || n == 0); 71 | NgxException::fail(n != NGX_AGAIN); 72 | 73 | //(n == NGX_AGAIN) 74 | } 75 | 76 | NgxStreamSession s(ev); 77 | auto& cf = this_module::conf().srv(s); 78 | 79 | //rev.timeout(cf.timeout, true); 80 | //rev.wait(); 81 | rev.wait_for(cf.timeout, true); 82 | } 83 | catch(const NgxException& e) 84 | { 85 | NgxStreamSession s(ev); 86 | 87 | NgxLogError(s).print("error = %d", e.code()); 88 | s.close(); 89 | } 90 | private: 91 | static void block_write_handler(ngx_event_t *ev) 92 | { 93 | // do nothing 94 | } 95 | 96 | }; 97 | 98 | #endif //_NDG_STREAM_DISCARD_HANDLER_HPP 99 | -------------------------------------------------------------------------------- /stream/discard/NdgStreamDiscardInit.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_STREAM_DISCARD_INIT_HPP 4 | #define _NDG_STREAM_DISCARD_INIT_HPP 5 | 6 | #include "NdgStreamDiscardConf.hpp" 7 | #include "NdgStreamDiscardHandler.hpp" 8 | 9 | class NdgStreamDiscardInit final 10 | { 11 | public: 12 | typedef NdgStreamDiscardConf conf_type; 13 | typedef NdgStreamDiscardHandler handler_type; 14 | typedef NdgStreamDiscardInit this_type; 15 | public: 16 | static ngx_command_t* cmds() 17 | { 18 | static ngx_command_t n[] = 19 | { 20 | { 21 | ngx_string("ndg_discard_time_out"), 22 | NgxTake(NGX_STREAM_SRV_CONF, 1), 23 | ngx_conf_set_msec_slot, 24 | NGX_STREAM_SRV_CONF_OFFSET, 25 | offsetof(conf_type, timeout), 26 | nullptr 27 | }, 28 | 29 | { 30 | ngx_string("ndg_stream_discard"), 31 | NgxTake(NGX_STREAM_SRV_CONF, 0), 32 | &this_type::set_discard, 33 | NGX_STREAM_SRV_CONF_OFFSET, 34 | 0, nullptr 35 | }, 36 | 37 | ngx_null_command 38 | }; 39 | 40 | return n; 41 | } 42 | public: 43 | static ngx_stream_module_t* ctx() 44 | { 45 | static ngx_stream_module_t c = 46 | { 47 | NGX_MODULE_NULL(4), 48 | 49 | &conf_type::create, 50 | &conf_type::merge, 51 | }; 52 | 53 | return &c; 54 | } 55 | public: 56 | static const ngx_module_t& module() 57 | { 58 | static ngx_module_t m = 59 | { 60 | NGX_MODULE_V1, 61 | 62 | ctx(), 63 | cmds(), 64 | 65 | NGX_STREAM_MODULE, 66 | NGX_MODULE_NULL(7), 67 | NGX_MODULE_V1_PADDING 68 | }; 69 | 70 | return m; 71 | } 72 | private: 73 | static char* set_discard(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) 74 | { 75 | boost::ignore_unused(cmd, conf); 76 | 77 | NgxStreamCoreModule::handler( 78 | cf, &handler_type::handler); 79 | 80 | return NGX_CONF_OK; 81 | } 82 | }; 83 | 84 | #endif //_NDG_STREAM_DISCARD_INIT_HPP 85 | 86 | -------------------------------------------------------------------------------- /stream/discard/config: -------------------------------------------------------------------------------- 1 | #./configure --add-module=$HOME/ngx_cpp_dev/modules/test 2 | 3 | ngx_module_type=STREAM 4 | ngx_module_name=ndg_stream_discard_module 5 | ngx_module_srcs="$ngx_addon_dir/ModNdgStreamDiscard.cpp" 6 | 7 | . auto/module 8 | 9 | ngx_addon_name=ndg_stream_discard_module 10 | 11 | -------------------------------------------------------------------------------- /stream/time/ModNdgStreamTime.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016-2017 2 | // Author: Chrono Law 3 | #include "NdgStreamTimeInit.hpp" 4 | 5 | auto ndg_stream_time_module = NdgStreamTimeInit::module(); 6 | 7 | 8 | -------------------------------------------------------------------------------- /stream/time/NdgStreamTimeConf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_STREAM_TIME_CONF_HPP 4 | #define _NDG_STREAM_TIME_CONF_HPP 5 | 6 | #include "NgxStreamAll.hpp" 7 | 8 | class NdgStreamTimeConf final 9 | { 10 | public: 11 | typedef NdgStreamTimeConf this_type; 12 | public: 13 | NdgStreamTimeConf() = default; 14 | ~NdgStreamTimeConf() = default; 15 | public: 16 | static void* create(ngx_conf_t* cf) 17 | { 18 | return NgxPool(cf).alloc(); 19 | } 20 | 21 | static char* merge(ngx_conf_t *cf, void *parent, void *child) 22 | { 23 | return NGX_CONF_OK; 24 | } 25 | public: 26 | static this_type& cast(void* p) 27 | { 28 | return *reinterpret_cast(p); 29 | } 30 | }; 31 | 32 | NGX_MOD_INSTANCE(NdgStreamTimeModule, ndg_stream_datetime_module, NdgStreamTimeConf) 33 | 34 | #endif //_NDG_STREAM_TIME_CONF_HPP 35 | -------------------------------------------------------------------------------- /stream/time/NdgStreamTimeHandler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_STREAM_TIME_HANDLER_HPP 4 | #define _NDG_STREAM_TIME_HANDLER_HPP 5 | 6 | #include 7 | 8 | #include "NdgStreamTimeConf.hpp" 9 | 10 | class NdgStreamTimeHandler final 11 | { 12 | public: 13 | typedef NdgStreamTimeHandler this_type; 14 | typedef NdgStreamTimeModule this_module; 15 | public: 16 | static void handler(ngx_stream_session_t *s) 17 | try 18 | { 19 | NgxConnection conn(s); 20 | 21 | NgxReadEvent rev = conn.read_event(); 22 | rev.handler(&this_type::block_read_handler); 23 | 24 | NgxWriteEvent wev = conn.write_event(); 25 | wev.handler(&this_type::time_write_handler); 26 | 27 | wev.process(); 28 | } 29 | catch(const NgxException& e) 30 | { 31 | NgxLogError(s).print("error = %d", e.code()); 32 | } 33 | private: 34 | static void time_write_handler(ngx_event_t *ev) 35 | try 36 | { 37 | NgxWriteEvent wev(ev); 38 | NgxConnection conn(ev); // = wev.connection(); 39 | 40 | // check timedout and error 41 | NgxException::fail(wev.expired(), NGX_ETIMEDOUT); 42 | NgxException::fail(conn.closed()); 43 | 44 | if(!wev.ready()) 45 | { 46 | //wev.timeout(100); 47 | //wev.wait(); 48 | wev.wait_for(100); 49 | 50 | return; 51 | } 52 | 53 | NgxPool pool(conn); 54 | 55 | NgxBuf buf = pool.buffer(20); 56 | buf.printf("%T", ngx_time()); 57 | buf.finish(); 58 | 59 | #if 0 60 | auto n = conn.send(buf.begin(), buf.size()); 61 | 62 | // for more readable 63 | //NgxException::fail(n <= 0 && n != NGX_EAGAIN); 64 | NgxException::require(n > 0 || n == NGX_EAGAIN); 65 | 66 | if(n == NGX_EAGAIN) 67 | { 68 | //wev.timeout(100); 69 | //wev.wait(); 70 | wev.wait_for(100); 71 | 72 | return; 73 | } 74 | 75 | // n > 0 76 | NgxStreamSession(conn).close(); 77 | #endif 78 | 79 | NgxChainNode n = pool.chain(); 80 | n.set(buf); 81 | n.finish(); 82 | 83 | NgxStreamSession s(conn); 84 | s.send(n); 85 | 86 | if(conn->buffered) 87 | { 88 | wev.wait_for(100); 89 | return; 90 | } 91 | 92 | s.close(); 93 | } 94 | catch(const NgxException& e) 95 | { 96 | //NgxWriteEvent wev(ev); 97 | //NgxConnection conn = wev.connection(); 98 | //NgxStreamSession s(conn); 99 | NgxStreamSession s(ev); 100 | 101 | //NgxLogError(s).print("error = %d", e.code()); 102 | s.close(e.code()); 103 | } 104 | private: 105 | static void block_read_handler(ngx_event_t *ev) 106 | { 107 | // do nothing 108 | } 109 | }; 110 | 111 | #endif //_NDG_STREAM_TIME_HANDLER_HPP 112 | -------------------------------------------------------------------------------- /stream/time/NdgStreamTimeInit.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016-2017 2 | // Author: Chrono Law 3 | #ifndef _NDG_STREAM_TIME_INIT_HPP 4 | #define _NDG_STREAM_TIME_INIT_HPP 5 | 6 | #include "NdgStreamTimeConf.hpp" 7 | #include "NdgStreamTimeHandler.hpp" 8 | 9 | class NdgStreamTimeInit final 10 | { 11 | public: 12 | typedef NdgStreamTimeConf conf_type; 13 | typedef NdgStreamTimeHandler handler_type; 14 | typedef NdgStreamTimeInit this_type; 15 | public: 16 | static ngx_command_t* cmds() 17 | { 18 | static ngx_command_t n[] = 19 | { 20 | { 21 | ngx_string("ndg_stream_time"), 22 | NgxTake(NGX_STREAM_SRV_CONF, 0), 23 | &this_type::set_time, 24 | NGX_STREAM_SRV_CONF_OFFSET, 25 | 0, nullptr 26 | }, 27 | 28 | ngx_null_command 29 | }; 30 | 31 | return n; 32 | } 33 | public: 34 | static ngx_stream_module_t* ctx() 35 | { 36 | static ngx_stream_module_t c = 37 | { 38 | NGX_MODULE_NULL(4), 39 | 40 | NGX_MODULE_NULL(2) 41 | //&conf_type::create, 42 | //&conf_type::merge, 43 | }; 44 | 45 | return &c; 46 | } 47 | public: 48 | static const ngx_module_t& module() 49 | { 50 | static ngx_module_t m = 51 | { 52 | NGX_MODULE_V1, 53 | 54 | ctx(), 55 | cmds(), 56 | 57 | NGX_STREAM_MODULE, 58 | NGX_MODULE_NULL(7), 59 | NGX_MODULE_V1_PADDING 60 | }; 61 | 62 | return m; 63 | } 64 | private: 65 | static char* set_time(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) 66 | { 67 | boost::ignore_unused(cmd, conf); 68 | 69 | NgxStreamCoreModule::handler( 70 | cf, &handler_type::handler); 71 | 72 | return NGX_CONF_OK; 73 | } 74 | }; 75 | 76 | #endif //_NDG_STREAM_TIME_INIT_HPP 77 | 78 | -------------------------------------------------------------------------------- /stream/time/config: -------------------------------------------------------------------------------- 1 | #./configure --add-module=$HOME/ngx_cpp_dev/modules/test 2 | 3 | ngx_module_type=STREAM 4 | ngx_module_name=ndg_stream_time_module 5 | ngx_module_srcs="$ngx_addon_dir/ModNdgStreamTime.cpp" 6 | 7 | . auto/module 8 | 9 | ngx_addon_name=ndg_stream_time_module 10 | 11 | -------------------------------------------------------------------------------- /t/echo.t: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016 by chrono 2 | 3 | use Test::Nginx::Socket 'no_plan'; 4 | 5 | run_tests(); 6 | 7 | __DATA__ 8 | 9 | === TEST 1 : echo no args 10 | 11 | --- config 12 | location = /echo { 13 | ndg_echo "hello nginx\n"; 14 | } 15 | 16 | --- request 17 | GET /echo 18 | 19 | --- response_body 20 | hello nginx 21 | 22 | === TEST 2 : echo with args 23 | 24 | --- config 25 | location = /echo { 26 | ndg_echo "hello\n"; 27 | } 28 | 29 | --- request 30 | GET /echo?chrono 31 | 32 | --- response_body 33 | chrono,hello 34 | -------------------------------------------------------------------------------- /t/filter.t: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016 by chrono 2 | 3 | use Test::Nginx::Socket 'no_plan'; 4 | 5 | run_tests(); 6 | 7 | __DATA__ 8 | 9 | === Test 1 : headers 10 | 11 | --- config 12 | location = /filter { 13 | ndg_echo "filter\n"; 14 | ndg_header x-name chrono; 15 | ndg_header x-value trigger; 16 | } 17 | 18 | --- request 19 | GET /filter 20 | 21 | --- response_body 22 | filter 23 | 24 | --- response_headers 25 | x-name : chrono 26 | x-value : trigger 27 | 28 | === Test 2 : footer 29 | 30 | --- config 31 | location = /filter { 32 | ndg_echo "hello\n"; 33 | ndg_footer "ocarina of time\n"; 34 | } 35 | 36 | --- request 37 | GET /filter 38 | 39 | --- response_body 40 | hello 41 | ocarina of time 42 | 43 | === Test 3 : headers and footer 44 | 45 | --- config 46 | location = /filter { 47 | ndg_echo "hello\n"; 48 | ndg_footer "ocarina of time\n"; 49 | ndg_header x-name chrono; 50 | ndg_header x-value trigger; 51 | } 52 | 53 | --- request 54 | GET /filter 55 | 56 | --- response_headers 57 | x-name : chrono 58 | x-value : trigger 59 | 60 | --- response_body 61 | hello 62 | ocarina of time 63 | 64 | --------------------------------------------------------------------------------