├── INSTALL
├── LICENSE
├── README.md
├── config
├── ngx_yar
├── .gitignore
├── CMakeLists.txt
├── yar.h
├── yar_client.c
├── yar_client.h
├── yar_common.h
├── yar_log.c
├── yar_log.h
├── yar_method.c
├── yar_method.h
├── yar_pack.c
├── yar_pack.h
├── yar_protocol.c
├── yar_protocol.h
├── yar_request.c
├── yar_request.h
├── yar_response.c
└── yar_response.h
├── php_tests
├── config.php
└── test1.php
├── src
├── ngx_yar_module_def.h
├── ngx_yar_module_handler.c
├── ngx_yar_module_handler.h
├── ngx_yar_module_impl.c
└── ngx_yar_module_impl.h
└── test
├── .gitignore
├── CMakeLists.txt
└── yar_test_method.c
/INSTALL:
--------------------------------------------------------------------------------
1 | see README.md
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
341 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ###Intro
2 |
3 | Yar是一个高效且简单的RPC协议。目前已经有[PHP语言版本](https://github.com/laruence/yar) 以及 [C语言版本](https://github.com/laruence/yar)。 C语言使用直接tcp对外提供服务。灵活性上略逊于http服务。
4 |
5 | ###Install
6 |
7 | 1. Install libcurl-devel
8 |
9 | 2. Install Msgpack-0.5.9(https://github.com/msgpack/msgpack-c/releases/download/cpp-0.5.9/msgpack-0.5.9.tar.gz)
10 |
11 |
12 | 3. Install libngx_yar
13 |
14 | $ git clone https://github.com/weixinhost/nginx_yar_module.git
15 | $ cd nginx_yar_module/ngx_yar
16 | $ cmake .
17 | $ make && make install
18 |
19 | 4. ReInstall Nginx
20 |
21 | $ cd nginx_source_dir/
22 | $ ./configure --add-module=/path/to/ngx_yar_module ....
23 | $ make && make install
24 |
25 |
26 |
27 | ###nginx server configure
28 |
29 | server {
30 |
31 | listen 80;
32 | server_name xxx;
33 |
34 | location / {
35 |
36 | yar_method_path "xxxx.so"; yar handler 库
37 |
38 | yar_timeout 100; yar handler超时
39 | yar_slow_timeout 500; 慢日志记录
40 |
41 | yar_bootstrap "bootstrap"; 每个request都首先调用该方法。
42 |
43 | yar_finalize "finalize" 每个request最后都调用该方法。
44 |
45 | yar_custom_config "";
46 | yar_on; 服务开启标识符
47 |
48 | }
49 |
50 | access_log "xxx.log" access;
51 | error_log "xxx.error.log" notice;
52 | }
53 |
54 |
55 |
56 | #####yar_method_path
57 |
58 | yar的方法程序库。
59 |
60 | void yar_method_test(yar_request *request, yar_response *response, void *cookie);
61 |
62 | 上面的说明是一个典型的yar方法声明。 yar_method_为前缀,使用该前缀的方法才允许被访问。除去前缀的就是真实的方法名。
63 |
64 |
65 | #####yar_timeout
66 |
67 | 每个方法调用允许最大的执行时间(bootstrap + handler + finalize)
68 |
69 | ####yar_custom_config
70 |
71 | 自定义文本。该配置最终将传入yar_bootstrap指定的符号中。
72 |
73 | #####yar_bootstrap
74 |
75 | 请求入口。适合做全局性的工作(全局资源初始化,全局参数检测)。
76 | 不指定或符号不存在则跳过
77 |
78 | typedef void (*yar_bootstrap_method)(void *config,uint config_len);
79 |
80 |
81 | ####yar_finalize
82 |
83 | handler调用后将触发该函数。
84 | 不指定或符号不存在则跳过
85 | typedef void (*yar_finalize_method)(yar_request *request, yar_response *response);
86 |
87 | ####yar_on
88 |
89 | 配置该项说明这个location正在对外提供yar服务。
90 |
91 |
92 | ####Devloper Guide
93 |
94 | 在源码包中的test目录为一个简单的种子程序。
95 |
96 |
97 |
98 | #####注意事项
99 |
100 | 1. 不主动对任何参数做内存写与释放的工作(比如 yar_request,yar_response)。 2. handler程序不应该执行过长时间(否则影响nginx吞吐量)。
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/config:
--------------------------------------------------------------------------------
1 | ngx_addon_name=ngx_http_yar_module
2 | HTTP_MODULES="$HTTP_MODULES ngx_http_yar_module"
3 |
4 | ngx_feature="Msgpack Library"
5 | ngx_feature_libs="-lmsgpack -lngx_yar -lcurl -lm"
6 | ngx_feature_run=no
7 | CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
8 | . auto/feature
9 |
10 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS
11 | $ngx_addon_dir/src/ngx_yar_module_handler.c
12 | $ngx_addon_dir/src/ngx_yar_module_impl.c
13 | "
--------------------------------------------------------------------------------
/ngx_yar/.gitignore:
--------------------------------------------------------------------------------
1 | CMakeCache.txt
2 | CMakeFiles
3 | Makefile
4 | cmake_install.cmake
5 | install_manifest.txt
6 | .idea
7 | *.so
8 |
--------------------------------------------------------------------------------
/ngx_yar/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
4 | SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
5 |
6 | project(ngx_yar)
7 | INCLUDE(CheckIncludeFiles)
8 | CHECK_INCLUDE_FILES(msgpack/msgpack.h HAVE_MSGPACK)
9 |
10 | IF(NOT HAVA_MSGPACK)
11 | MESSAGE("library `msgpack` not found.")
12 | ENDIF(NOT HAVA_MSGPACK)
13 |
14 | CHECK_INCLUDE_FILES(curl/curl.h HAVE_CURL)
15 |
16 | IF(NOT HAVE_CURL)
17 | MESSAGE("library `curl` not found.")
18 | ENDIF(NOT HAVE_CURL)
19 |
20 | set(HEADER_LIST yar.h yar_common.h yar_response.h yar_request.h yar_pack.h yar_protocol.h yar_log.h yar_method.h yar_client.h)
21 | set(SRC_LIST ${HEADER_LIST} yar_response.c yar_request.c yar_pack.c yar_protocol.c yar_log.c yar_method.c yar_client.c)
22 |
23 | ADD_LIBRARY(ngx_yar SHARED ${SRC_LIST})
24 | target_link_libraries(ngx_yar msgpack)
25 | install(TARGETS ngx_yar DESTINATION lib)
26 | install(FILES ${HEADER_LIST} DESTINATION include/ngx_yar)
--------------------------------------------------------------------------------
/ngx_yar/yar.h:
--------------------------------------------------------------------------------
1 | #ifndef __yar_H_
2 | #define __yar_H_
3 |
4 | #include
5 | #include
6 | #include "yar_common.h"
7 | #include "yar_pack.h"
8 | #include "yar_protocol.h"
9 | #include "yar_request.h"
10 | #include "yar_response.h"
11 | #include "yar_log.h"
12 | #include "yar_method.h"
13 | #include "yar_client.h"
14 |
15 | #endif //yar.h_H_
16 |
--------------------------------------------------------------------------------
/ngx_yar/yar_client.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Yar - Concurrent RPC Server for PHP, C etc
3 | *
4 | * Copyright (C) 2012-2012 Xinchen Hui
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | #ifdef HAVE_CONFIG_H
20 | #include "config.h"
21 | #endif
22 |
23 | #include /* for fprintf */
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include /* for sockets */
30 | #include /* for un */
31 | #include /* for gethostbyname */
32 |
33 | #include "yar_common.h"
34 | #include "yar_pack.h"
35 | #include "yar_protocol.h"
36 | #include "yar_response.h"
37 | #include "yar_request.h"
38 | #include "yar_client.h"
39 |
40 | void yar_client_destroy(yar_client *client) /* {{{ */ {
41 | if (client->fd) {
42 | close(client->fd);
43 | }
44 |
45 | free(client);
46 | }
47 | /* }}} */
48 |
49 | static yar_response * yar_client_caller(yar_client *client, char *method, uint num_args, yar_packager *parameters[]) /* {{{ */ {
50 | int bytes_sent, select_result;
51 | uint bytes_left, totolly_read;
52 | yar_header *response_header = NULL;
53 | yar_response *response;
54 | yar_request *request;
55 | yar_header header = {0};
56 | yar_payload payload = {0};
57 | struct timeval tv;
58 | fd_set readfds, writefds;
59 |
60 | if (client->timeout){
61 | tv.tv_sec = client->timeout;
62 | } else {
63 | tv.tv_sec = 1; /* default 1 second */
64 | }
65 | tv.tv_usec = 0;
66 |
67 | request = calloc(1, sizeof(yar_request));
68 | request->id = 1000; /* dummy id */
69 | request->method = strdup(method);
70 | request->mlen = strlen(method);
71 | if (num_args) {
72 | uint i;
73 | yar_packager *packager = yar_pack_start_array(num_args);
74 | for (i=0;iid, YAR_CLIENT_NAME, NULL, payload.size - sizeof(yar_header), client->persistent? YAR_PROTOCOL_PERSISTENT : 0);
89 |
90 | memcpy(payload.data, (char *)&header, sizeof(yar_header));
91 | memcpy(payload.data + sizeof(yar_header), YAR_PACKAGER, sizeof(YAR_PACKAGER));
92 | yar_request_free(request);
93 | free(request);
94 |
95 | FD_ZERO(&writefds);
96 | FD_SET(client->fd, &writefds);
97 |
98 | bytes_left = payload.size;
99 |
100 | write_wait:
101 | if ((select_result = select(client->fd + 1, NULL, &writefds, NULL, &tv)) == 0) {
102 |
103 | free(payload.data);
104 | return NULL;
105 | } else if (select == -1) {
106 |
107 | free(payload.data);
108 | return NULL;
109 | }
110 |
111 | if (!FD_ISSET(client->fd, &writefds)) {
112 | goto write_wait;
113 | } else {
114 | do {
115 | bytes_sent = send(client->fd, payload.data + payload.size - bytes_left, bytes_left, 0);
116 | } while (bytes_sent == -1 && errno == EINTR);
117 |
118 | if (bytes_sent < 0) {
119 |
120 | free(payload.data);
121 | return NULL;
122 | }
123 |
124 | bytes_left -= bytes_sent;
125 | if (bytes_left) {
126 | goto write_wait;
127 | }
128 | }
129 |
130 | free(payload.data);
131 |
132 | FD_ZERO(&readfds);
133 | FD_SET(client->fd, &readfds);
134 |
135 | response = calloc(1, sizeof(yar_response));
136 | totolly_read = 0;
137 |
138 | read_wait:
139 | if ((select_result = select(client->fd + 1, &readfds, NULL, NULL, &tv)) == 0) {
140 |
141 | yar_response_free(response);
142 | free(response);
143 | return NULL;
144 | } else if (select_result == -1) {
145 |
146 | yar_response_free(response);
147 | free(response);
148 | return NULL;
149 | }
150 |
151 | if (!FD_ISSET(client->fd, &readfds)) {
152 | goto read_wait;
153 | } else {
154 | int bytes_read = 0;
155 | if (!response_header) {
156 | char buf[sizeof(yar_header)];
157 | do {
158 | bytes_read = recv(client->fd, buf, sizeof(buf), 0);
159 | } while (bytes_read == -1 && errno == EINTR);
160 |
161 | if (bytes_read == 0) {
162 |
163 | yar_response_free(response);
164 | free(response);
165 | return NULL;
166 | } else if (bytes_read < 0) {
167 |
168 | yar_response_free(response);
169 | free(response);
170 | return NULL;
171 | }
172 |
173 | response_header = (yar_header *)buf;
174 | if (!yar_protocol_parse(response_header)) {
175 |
176 | yar_response_free(response);
177 | free(response);
178 | return NULL;
179 | }
180 | if (!response->payload.data) {
181 | response->payload.data = malloc(sizeof(yar_header) + response_header->body_len);
182 | response->payload.size = sizeof(yar_header) + response_header->body_len;
183 | }
184 | memcpy(response->payload.data + totolly_read, buf, bytes_read);
185 | totolly_read += bytes_read;
186 | }
187 |
188 | do {
189 | bytes_read = recv(client->fd, response->payload.data + bytes_read, response->payload.size - bytes_read, 0);
190 | } while (bytes_read == -1 && errno == EINTR);
191 |
192 | if (bytes_read == 0) {
193 |
194 | yar_response_free(response);
195 | free(response);
196 | return NULL;
197 | } else if (bytes_read < 0) {
198 |
199 | yar_response_free(response);
200 | free(response);
201 | return NULL;
202 | }
203 |
204 | totolly_read += bytes_read;
205 | if (totolly_read < response_header->body_len + sizeof(yar_header)) {
206 | goto read_wait;
207 | }
208 |
209 | if (!yar_response_unpack(response, response->payload.data, response->payload.size, sizeof(yar_header) + sizeof(YAR_PACKAGER))) {
210 |
211 | yar_response_free(response);
212 | free(response);
213 | return NULL;
214 | }
215 |
216 | return response;
217 | }
218 |
219 | }
220 | /* }}} */
221 |
222 |
223 |
224 | static size_t yar_client_http_write_func (void *contents, size_t size, size_t nmemb, void *userp) {
225 |
226 | size_t realsize = size * nmemb;
227 |
228 | yar_client_http_write_buffer *mem = (yar_client_http_write_buffer *) userp;
229 |
230 | if(!mem->buf){
231 |
232 | mem->buf = (void *)calloc(1,realsize);
233 |
234 | }else{
235 |
236 | mem->buf = realloc(mem->buf,mem->len + realsize);
237 |
238 | }
239 |
240 |
241 | memcpy(mem->buf + mem->len,contents,realsize);
242 |
243 | mem->len += realsize;
244 |
245 | return realsize;
246 | }
247 |
248 |
249 | static yar_response * yar_client_http_caller(yar_client *client, char *method, uint num_args, yar_packager *parameters[]){
250 |
251 | int bytes_sent, select_result;
252 | uint bytes_left, totolly_read;
253 | yar_header *response_header = NULL;
254 | yar_response *response = NULL;
255 | yar_request *request = NULL;
256 | yar_header header = {0};
257 | yar_payload payload = {0};
258 | struct timeval tv;
259 | fd_set readfds, writefds;
260 |
261 | if (client->timeout){
262 | tv.tv_sec = client->timeout;
263 | } else {
264 | tv.tv_sec = 1; /* default 1 second */
265 | }
266 | tv.tv_usec = 0;
267 |
268 | request = calloc(1, sizeof(yar_request));
269 | request->id = 1000; /* dummy id */
270 | request->method = strdup(method);
271 | request->mlen = strlen(method);
272 | if (num_args) {
273 | uint i;
274 | yar_packager *packager = yar_pack_start_array(num_args);
275 | for (i=0;iid, YAR_CLIENT_NAME, NULL, payload.size - sizeof(yar_header), client->persistent? YAR_PROTOCOL_PERSISTENT : 0);
293 |
294 | memcpy(payload.data, (char *)&header, sizeof(yar_header));
295 |
296 | memcpy(payload.data + sizeof(yar_header), YAR_PACKAGER, sizeof(YAR_PACKAGER));
297 |
298 | yar_request_free(request);
299 |
300 | free(request);
301 |
302 | curl_global_init(CURL_GLOBAL_NOTHING);
303 |
304 | CURL *curl = curl_easy_init();
305 |
306 | curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1);
307 |
308 | curl_easy_setopt(curl, CURLOPT_USERAGENT, YAR_CLIENT_NAME);
309 |
310 | curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, 15 * 30);
311 |
312 | curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
313 |
314 | curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
315 |
316 | curl_easy_setopt(curl, CURLOPT_URL, client->hostname);
317 |
318 | curl_easy_setopt(curl, CURLOPT_TIMEOUT, client->timeout ? client->timeout : 5);
319 |
320 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, yar_client_http_write_func);
321 |
322 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &client->write_buffer);
323 |
324 | curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST,"POST");
325 |
326 | curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload.data);
327 |
328 | curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, payload.size);
329 |
330 | int err_code = curl_easy_perform (curl);
331 |
332 | if(err_code != 0 || client->write_buffer.len < sizeof(yar_header)){
333 |
334 | goto clean_curl;
335 |
336 | }
337 |
338 |
339 |
340 |
341 | response_header = (yar_header *)client->write_buffer.buf;
342 |
343 | if (!yar_protocol_parse(response_header)) {
344 |
345 |
346 |
347 | goto clean_curl;
348 |
349 | }
350 |
351 | response = calloc(1,sizeof(yar_response));
352 |
353 | response->payload.data = malloc(sizeof(yar_header) + client->write_buffer.len);
354 |
355 | response->payload.size = sizeof(yar_header) + client->write_buffer.len;
356 |
357 | memcpy(response->payload.data , client->write_buffer.buf,client->write_buffer.len);
358 |
359 | if (!yar_response_unpack(response, response->payload.data, response->payload.size, sizeof(yar_header) + sizeof(YAR_PACKAGER))) {
360 |
361 | goto clean_curl;
362 |
363 | }
364 |
365 | clean_curl :
366 | {
367 |
368 | free(payload.data);
369 |
370 |
371 | if(client->write_buffer.buf) {
372 |
373 | free (client->write_buffer.buf);
374 |
375 | client->write_buffer.len = 0;
376 |
377 | client->write_buffer.buf = NULL;
378 | }
379 |
380 | curl_easy_cleanup(curl);
381 | curl_global_cleanup();
382 | };
383 |
384 | return response;
385 |
386 | }
387 |
388 |
389 |
390 | yar_client * yar_client_init(char *hostname) /* {{{ */ {
391 | struct sockaddr sa;
392 | int sockfd;
393 | yar_client *client = calloc(1, sizeof(yar_client));
394 |
395 | client->hostname = hostname;
396 | client->call = yar_client_caller;
397 | client->protocol = YAR_CLIENT_PROTOCOL_SOCK;
398 | client->write_buffer.buf = NULL;
399 | client->write_buffer.len = 0;
400 | client->timeout = 0;
401 |
402 | if (strncasecmp(hostname, "http://", sizeof("http://") -1) == 0
403 | || strncasecmp(hostname, "https://", sizeof("https://") -1) == 0) {
404 |
405 | client->protocol = YAR_CLIENT_PROTOCOL_HTTP;
406 | client->call = yar_client_http_caller;
407 |
408 | return client;
409 |
410 | } else if (hostname[0] == '/') {
411 | /* unix domain socket */
412 | struct sockaddr_un *usa;
413 | usa = (struct sockaddr_un *)&sa;
414 | if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0) == -1)) {
415 |
416 | free(client);
417 | return NULL;
418 | }
419 | usa->sun_family = AF_UNIX;
420 | memcpy(usa->sun_path, hostname, strlen(hostname) + 1);
421 | } else {
422 | /* IPV4, we don't support IPV6 for now */
423 | char *delim, *p, host[1024];
424 | int port;
425 | struct hostent *hptr;
426 | struct sockaddr_in *isa;
427 | if ((delim = strchr(hostname, ':'))) {
428 | memcpy(host, hostname, delim - hostname);
429 | host[delim - hostname] = '\0';
430 | port = atoi(delim + 1);
431 | } else {
432 |
433 | free(client);
434 | return NULL;
435 | }
436 |
437 | if ((hptr = gethostbyname(host)) == NULL) {
438 |
439 | free(client);
440 | return NULL;
441 | }
442 |
443 | p = hptr->h_addr;
444 | if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
445 |
446 | free(client);
447 | return NULL;
448 | }
449 |
450 | switch (hptr->h_addrtype) {
451 | case AF_INET:
452 | {
453 | int val = 1;
454 | isa = (struct sockaddr_in *)&sa;
455 | bzero(isa, sizeof(struct sockaddr_in));
456 |
457 | isa->sin_family = AF_INET;
458 | isa->sin_port = htons(port);
459 | memcpy(&isa->sin_addr, p, sizeof(struct in_addr));
460 |
461 | setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&val, sizeof(val));
462 | }
463 | break;
464 | default:
465 |
466 | close(sockfd);
467 | free(client);
468 | return NULL;
469 | }
470 | }
471 |
472 | if (connect(sockfd, (const struct sockaddr *)&sa, sizeof(sa)) == -1) {
473 |
474 | close(sockfd);
475 | free(client);
476 | return NULL;
477 | }
478 |
479 | yar_set_non_blocking(sockfd);
480 |
481 | client->fd = sockfd;
482 |
483 | return client;
484 | }
485 | /* }}} */
486 |
487 | int yar_client_set_opt(yar_client *client, yar_client_opt opt, void *val) /* {{{ */ {
488 | switch (opt) {
489 | case YAR_PERSISTENT_LINK:
490 | client->persistent = *(int *)val;
491 | break;
492 | case YAR_CONNECT_TIMEOUT:
493 | client->timeout = *(int *)val;
494 | break;
495 | default:
496 | return 0;
497 | }
498 | return 1;
499 | }
500 | /* }}} */
501 |
502 | const void * yar_client_get_opt(yar_client *client, yar_client_opt opt) /* {{{ */ {
503 | switch (opt) {
504 | case YAR_PERSISTENT_LINK:
505 | return &client->persistent;
506 | break;
507 | case YAR_CONNECT_TIMEOUT:
508 | return &client->timeout;
509 | break;
510 | default:
511 | return NULL;
512 | }
513 | }
514 | /* }}} */
515 |
516 | /*
517 | * Local variables:
518 | * tab-width: 4
519 | * c-basic-offset: 4
520 | * End:
521 | * vim600: noet sw=4 ts=4 fdm=marker
522 | * vim<600: sw=4 ts=4
523 | */
--------------------------------------------------------------------------------
/ngx_yar/yar_client.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Yar - Concurrent RPC Server for PHP, C etc
3 | *
4 | * Copyright (C) 2012-2012 Xinchen Hui
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | #ifndef YAR_CLIENT_H
20 | #define YAR_CLIENT_H
21 |
22 | #include
23 | #include
24 |
25 | #define YAR_CLIENT_NAME "Yar(C)-"YAR_VERSION
26 |
27 | typedef struct _yar_client yar_client;
28 |
29 | typedef yar_response * (*yar_client_call)(yar_client *client, char *method, uint num_args, yar_packager *packager[]);
30 |
31 | typedef struct {
32 |
33 | void *buf;
34 | int len;
35 | } yar_client_http_write_buffer;
36 |
37 | typedef enum _yar_client_opt {
38 | YAR_PERSISTENT_LINK = 1,
39 | YAR_CONNECT_TIMEOUT
40 | } yar_client_opt;
41 |
42 | typedef enum {
43 |
44 | YAR_CLIENT_PROTOCOL_SOCK = 1,
45 | YAR_CLIENT_PROTOCOL_HTTP
46 |
47 | } yar_client_net_protocol;
48 |
49 | struct _yar_client {
50 | int fd;
51 | char *hostname;
52 | int persistent;
53 | int timeout;
54 | yar_client_call call;
55 |
56 | CURL* curl_handle;
57 |
58 | yar_client_http_write_buffer write_buffer;
59 |
60 | yar_client_net_protocol protocol;
61 |
62 | };
63 |
64 |
65 |
66 | yar_client * yar_client_init(char *hostname);
67 | int yar_client_set_opt(yar_client *client, yar_client_opt opt, void *val);
68 | const void * yar_client_get_opt(yar_client *client, yar_client_opt opt);
69 |
70 | void yar_client_destroy(yar_client *client);
71 | #endif
72 | /*
73 | * Local variables:
74 | * tab-width: 4
75 | * c-basic-offset: 4
76 | * End:
77 | * vim600: noet sw=4 ts=4 fdm=marker
78 | * vim<600: sw=4 ts=4
79 | */
--------------------------------------------------------------------------------
/ngx_yar/yar_common.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Yar - Concurrent RPC Server for PHP, C etc
3 | *
4 | * Copyright (C) 2012-2012 Xinchen Hui
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | #ifndef YAR_COMMON_H
20 | #define YAR_COMMON_H
21 |
22 | #include /* for fcntl */
23 |
24 | #define YAR_OKEY 0x0
25 | #define YAR_DEBUG 0x1
26 | #define YAR_NOTICE 0x2
27 | #define YAR_WARNING 0x4
28 | #define YAR_ERROR 0x8
29 |
30 | #define YAR_VERSION "0.0.1"
31 |
32 | typedef struct _yar_payload {
33 | char *data;
34 | uint size;
35 | } yar_payload;
36 |
37 | static inline int yar_set_non_blocking(int fd) {
38 | int flags = fcntl(fd, F_GETFL);
39 | if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
40 | return 0;
41 | }
42 | return 1;
43 | }
44 |
45 | #endif
46 | /*
47 | * Local variables:
48 | * tab-width: 4
49 | * c-basic-offset: 4
50 | * End:
51 | * vim600: noet sw=4 ts=4 fdm=marker
52 | * vim<600: sw=4 ts=4
53 | */
54 |
--------------------------------------------------------------------------------
/ngx_yar/yar_log.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Yar - Concurrent RPC Server for PHP, C etc
3 | *
4 | * Copyright (C) 2012-2012 Xinchen Hui
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | #include /* for va_list */
20 | #include /* for fprintf */
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include "yar_common.h"
28 | #include "yar_log.h"
29 |
30 | typedef struct _yar_logger {
31 | FILE *fp;
32 | int pipe;
33 | int enable;
34 | int level;
35 | const char *hostname;
36 | } yar_logger;
37 |
38 | static yar_logger *logger;
39 |
40 | int yar_logger_init(const char *path, int level) /* {{{ */ {
41 | yar_logger *lg = calloc(1, sizeof(yar_logger));
42 | lg->enable = 1;
43 | if (path) {
44 | if (path[0] != '|') {
45 | lg->fp = fopen(path, "a");
46 | } else {
47 | lg->pipe = 1;
48 | lg->fp = popen(path + 1, "w");
49 | }
50 | if (!lg->fp) {
51 | free(lg);
52 | alog(YAR_ERROR, "Failed to start lg '%s'", strerror(errno));
53 | return 0;
54 | }
55 | }
56 | lg->level = level;
57 | logger = lg;
58 | return 1;
59 | }
60 | /* }}} */
61 |
62 | int yar_logger_setopt(yar_logger_opt opt, void *value) /* {{{ */ {
63 | if (!logger) {
64 | return 0;
65 | }
66 |
67 | switch (opt) {
68 | case YAR_LOGGER_HOSTNAME:
69 | logger->hostname = (const char *)value;
70 | break;
71 | default:
72 | break;
73 | }
74 | return 1;
75 | }
76 | /* }}} */
77 |
78 | void yar_logger_destroy() /* {{{ */ {
79 | if (logger->fp) {
80 | if (logger->pipe) {
81 | pclose(logger->fp);
82 | } else {
83 | fclose(logger->fp);
84 | }
85 | }
86 | free(logger);
87 | logger = NULL;
88 | }
89 | /* }}} */
90 |
91 | void yar_log_ex(int type, const char *fmt, ...) /* {{{ */ {
92 | char buf[1024];
93 | va_list args;
94 | char *stype, *stv;
95 | time_t tv;
96 | uint len;
97 |
98 | if (logger && (!logger->enable || (type != YAR_OKEY && type < logger->level))) {
99 | return;
100 | }
101 |
102 | switch (type) {
103 | case YAR_OKEY:
104 | stype = "OKEY";
105 | break;
106 | case YAR_NOTICE:
107 | stype = "NOTICE";
108 | break;
109 | case YAR_DEBUG:
110 | stype = "DEBUG";
111 | break;
112 | case YAR_WARNING:
113 | stype = "WARN";
114 | break;
115 | case YAR_ERROR:
116 | stype = "ERROR";
117 | break;
118 | default:
119 | stype = "";
120 | break;
121 | }
122 |
123 | va_start(args, fmt);
124 | len = vsnprintf(buf, sizeof(buf), fmt, args);
125 | va_end(args);
126 |
127 | if (len >= sizeof(buf)) {
128 | memcpy(buf + sizeof(buf) - sizeof("..."), "...", sizeof("...") - 1);
129 | len = sizeof(buf) - 1;
130 | }
131 | buf[len] = '\0';
132 |
133 | tv = time(NULL);
134 | stv = ctime(&tv);
135 | if (logger && logger->fp) {
136 | fprintf(logger->fp, "%s [%.*s] %s: %s\n",
137 | logger->hostname? logger->hostname : "-", (int)(strlen(stv) - 1), stv, stype, buf);
138 | fflush(logger->fp);
139 | } else {
140 | fprintf(stderr, "%s [%.*s] %s: %s\n",
141 | logger && logger->hostname? logger->hostname : "-", (int)(strlen(stv) - 1), stv, stype, buf);
142 | }
143 |
144 | return;
145 | }
146 | /* }}} */
147 |
148 | /*
149 | * Local variables:
150 | * tab-width: 4
151 | * c-basic-offset: 4
152 | * End:
153 | * vim600: noet sw=4 ts=4 fdm=marker
154 | * vim<600: sw=4 ts=4
155 | */
156 |
--------------------------------------------------------------------------------
/ngx_yar/yar_log.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Yar - Concurrent RPC Server for PHP, C etc
3 | *
4 | * Copyright (C) 2012-2012 Xinchen Hui
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | #ifndef YAR_LOG_H
20 | #define YAR_LOG_H
21 |
22 | #define alog(type, ...) yar_log_ex(type, __VA_ARGS__)
23 |
24 | typedef enum _yar_logger_opt {
25 | YAR_LOGGER_HOSTNAME
26 | } yar_logger_opt;
27 |
28 | void yar_log_ex(int type, const char *fmt, ...);
29 | int yar_logger_init(const char *path, int mask);
30 | int yar_logger_setopt(yar_logger_opt opt, void *value);
31 | void yar_logger_destroy();
32 |
33 | #endif
34 |
35 | /*
36 | * Local variables:
37 | * tab-width: 4
38 | * c-basic-offset: 4
39 | * End:
40 | * vim600: noet sw=4 ts=4 fdm=marker
41 | * vim<600: sw=4 ts=4
42 | */
43 |
--------------------------------------------------------------------------------
/ngx_yar/yar_method.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "yar_common.h"
6 | #include "yar_pack.h"
7 | #include "yar_method.h"
8 |
9 |
10 | struct {
11 |
12 | size_t len;
13 | yar_method_t method_list[MAX_YAR_METHOD_LENGTH];
14 |
15 | } _yar_method_list;
16 |
17 | extern yar_method_init_callback yar_method_init_handler;
18 |
19 |
20 |
21 | yar_method_t* yar_method_register(char *name,size_t len,yar_method method){
22 |
23 | if(_yar_method_list.len >= MAX_YAR_METHOD_LENGTH) return NULL;
24 |
25 | yar_method_t* m = &_yar_method_list.method_list[_yar_method_list.len];
26 |
27 | m->name = name;
28 | m->len = len;
29 | m->method = method;
30 |
31 | _yar_method_list.len++;
32 | return &_yar_method_list.method_list[_yar_method_list.len - 1];
33 |
34 | }
35 |
36 | yar_method_t* yar_method_unregister(char *name, size_t len){
37 |
38 | yar_method_t *m = yar_method_find (name,len);
39 |
40 | if(!m) return NULL;
41 |
42 | m->name = NULL;
43 | m->len = 0;
44 | m->method = NULL;
45 |
46 | return m;
47 | }
48 |
49 |
50 | yar_method_t* yar_method_find(char *name, size_t len){
51 |
52 | if(_yar_method_list.len < 1) return NULL;
53 |
54 | unsigned int i =0;
55 |
56 | for(;i<_yar_method_list.len;i++){
57 |
58 | yar_method_t *method = &(_yar_method_list.method_list[i]);
59 |
60 | if(strncmp(method->name,name,len) == 0){
61 | return method;
62 | }
63 | }
64 |
65 | return NULL;
66 |
67 | }
68 |
69 |
70 |
71 | int yar_method_init(void){
72 |
73 |
74 | return 1;
75 | }
--------------------------------------------------------------------------------
/ngx_yar/yar_method.h:
--------------------------------------------------------------------------------
1 | #ifndef __yar_method_H_
2 | #define __yar_method_H_
3 |
4 | #define MAX_YAR_METHOD_LENGTH 32
5 |
6 |
7 | #include "yar_request.h"
8 | #include "yar_response.h"
9 |
10 | typedef void (*yar_method)(yar_request *request, yar_response *response, void *cookie);
11 | typedef void(*yar_method_init_callback)(void);
12 |
13 | typedef struct _yar_method
14 | {
15 |
16 | char *name;
17 | size_t len;
18 | yar_method method;
19 | } yar_method_t;
20 |
21 |
22 | yar_method_t* yar_method_register(char *name,size_t len,yar_method method);
23 | yar_method_t* yar_method_unregister(char *name, size_t len);
24 | yar_method_t* yar_method_find(char *name, size_t len);
25 |
26 | int yar_method_init(void);
27 |
28 |
29 | #endif //yar_method.h_H_
30 |
--------------------------------------------------------------------------------
/ngx_yar/yar_pack.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Yar - Concurrent RPC Server for PHP, C etc
3 | *
4 | * Copyright (C) 2012-2012 Xinchen Hui
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | #include
20 | #include /* for va_list */
21 | #include
22 | #include "msgpack.h"
23 |
24 | #include "yar_common.h"
25 | #include "yar_pack.h"
26 |
27 | struct _yar_packager {
28 | msgpack_packer *pk;
29 | msgpack_sbuffer *bf;
30 | };
31 |
32 | struct _yar_data {
33 | msgpack_object obj;
34 | };
35 |
36 | struct _yar_unpackager {
37 | msgpack_unpacked msg;
38 | };
39 |
40 | struct _yar_unpack_iterator {
41 | uint size;
42 | uint position;
43 | yar_data *data;
44 | };
45 |
46 | yar_packager * yar_pack_start(yar_data_type type, uint size) /* {{{ */ {
47 | yar_packager *packager = malloc(sizeof(yar_packager));
48 |
49 | packager->bf = msgpack_sbuffer_new();
50 | packager->pk = msgpack_packer_new(packager->bf, msgpack_sbuffer_write);
51 |
52 | switch (type) {
53 | case YAR_DATA_ARRAY:
54 | msgpack_pack_array(packager->pk, size);
55 | break;
56 | case YAR_DATA_MAP:
57 | msgpack_pack_map(packager->pk, size);
58 | break;
59 | default:
60 | break;
61 | }
62 |
63 | return packager;
64 | }
65 | /* }}} */
66 |
67 | int yar_pack_push_array(yar_packager *packager, uint size) /* {{{ */ {
68 | msgpack_packer *pk = packager->pk;
69 |
70 | return msgpack_pack_array(pk, size) < 0? 0: 1;
71 | }
72 | /* }}} */
73 |
74 | int yar_pack_push_map(yar_packager *packager, uint size) /* {{{ */ {
75 | msgpack_packer *pk = packager->pk;
76 |
77 | return msgpack_pack_map(pk, size) < 0? 0 : 1;
78 | }
79 | /* }}} */
80 |
81 | int yar_pack_push_null(yar_packager *packager) /* {{{ */ {
82 | msgpack_packer *pk = packager->pk;
83 |
84 | msgpack_pack_nil(pk);
85 |
86 | return 1;
87 | }
88 | /* }}} */
89 |
90 | int yar_pack_push_bool(yar_packager *packager, int val) /* {{{ */ {
91 | msgpack_packer *pk = packager->pk;
92 |
93 | if (val == 0) {
94 | if (msgpack_pack_false(pk) < 0) {
95 | return 0;
96 | }
97 | } else {
98 | if (msgpack_pack_true(pk) < 0) {
99 | return 0;
100 | }
101 | }
102 |
103 | return 1;
104 | }
105 | /* }}} */
106 |
107 | int yar_pack_push_long(yar_packager *packager, long num) /* {{{ */ {
108 | msgpack_packer *pk = packager->pk;
109 |
110 | return msgpack_pack_int64(pk, num) < 0? 0 : 1;
111 | }
112 | /* }}} */
113 |
114 | int yar_pack_push_ulong(yar_packager *packager, ulong num) /* {{{ */ {
115 | msgpack_packer *pk = packager->pk;
116 |
117 | return msgpack_pack_uint64(pk, num) < 0? 0 : 1;
118 | }
119 | /* }}} */
120 |
121 | int yar_pack_push_double(yar_packager *packager, double num) /* {{{ */ {
122 | msgpack_packer *pk = packager->pk;
123 |
124 | return msgpack_pack_double(pk, num) < 0? 0 : 1;
125 | }
126 | /* }}} */
127 |
128 | int yar_pack_push_string(yar_packager *packager, char *str, uint len) /* {{{ */ {
129 | int ret;
130 | msgpack_packer *pk = packager->pk;
131 |
132 | ret = msgpack_pack_raw(pk, len);
133 |
134 | if (ret < 0) {
135 | return 0;
136 | }
137 |
138 | if (msgpack_pack_raw_body(pk, str, len) < 0) {
139 | return 0;
140 | }
141 |
142 | return 1;
143 | }
144 | /* }}} */
145 |
146 | int yar_pack_push_data(yar_packager *packager, const yar_data *data) /* {{{ */ {
147 | msgpack_packer *pk = packager->pk;
148 |
149 | return msgpack_pack_object(pk, *(msgpack_object *)data) < 0? 0 : 1;
150 | }
151 | /* }}} */
152 |
153 | int yar_pack_push_packager(yar_packager *packager, yar_packager *data) /* {{{ */ {
154 | msgpack_sbuffer *buffer = packager->bf;
155 | yar_payload payload = {0};
156 |
157 | yar_pack_to_string(data, &payload);
158 | return msgpack_sbuffer_write(buffer, payload.data, payload.size) < 0? 0 : 1;
159 | }
160 | /* }}} */
161 |
162 | int yar_pack_to_string(yar_packager *packager, yar_payload *payload) /* {{{ */ {
163 | msgpack_sbuffer *bf = packager->bf;
164 | payload->size = bf->size;
165 | payload->data = bf->data;
166 | return 1;
167 | }
168 | /* }}} */
169 |
170 | void yar_pack_free(yar_packager *packager) /* {{{ */ {
171 | msgpack_sbuffer_free(packager->bf);
172 | msgpack_packer_free(packager->pk);
173 | free(packager);
174 | }
175 | /* }}} */
176 |
177 | void yar_unpack_free(yar_unpackager *unpk) /* {{{ */ {
178 | msgpack_unpacked_destroy(&unpk->msg);
179 | free(unpk);
180 | }
181 | /* }}} */
182 |
183 | yar_unpackager * yar_unpack_init(char *data, uint len) /* {{{ */ {
184 | yar_unpackager *unpk = malloc(sizeof(yar_unpackager));
185 | msgpack_unpacked_init(&unpk->msg);
186 | if (!msgpack_unpack_next(&unpk->msg, data, len, NULL)) {
187 | yar_unpack_free(unpk);
188 | return NULL;
189 | }
190 | return unpk;
191 | }
192 | /* }}} */
193 |
194 | const yar_data * yar_unpack_unpack(yar_unpackager *unpk) /* {{{ */ {
195 | return (const yar_data *)&unpk->msg.data;
196 | }
197 | /* }}} */
198 |
199 | yar_data_type yar_unpack_data_type(const yar_data *data, uint *size) /* {{{ */ {
200 | msgpack_object *obj = (msgpack_object *)data;
201 |
202 | switch (obj->type) {
203 | case MSGPACK_OBJECT_NIL:
204 | return YAR_DATA_NULL;
205 | case MSGPACK_OBJECT_BOOLEAN:
206 | return YAR_DATA_BOOL;
207 | case MSGPACK_OBJECT_POSITIVE_INTEGER:
208 | return YAR_DATA_ULONG;
209 | case MSGPACK_OBJECT_NEGATIVE_INTEGER:
210 | return YAR_DATA_LONG;
211 | case MSGPACK_OBJECT_DOUBLE:
212 | return YAR_DATA_DOUBLE;
213 | case MSGPACK_OBJECT_RAW:
214 | *size = obj->via.raw.size;
215 | return YAR_DATA_STRING;
216 | case MSGPACK_OBJECT_ARRAY:
217 | *size = obj->via.array.size;
218 | return YAR_DATA_ARRAY;
219 | case MSGPACK_OBJECT_MAP:
220 | *size = obj->via.map.size;
221 | return YAR_DATA_MAP;
222 | }
223 | return 0;
224 | }
225 | /* }}} */
226 |
227 | int yar_unpack_data_value(const yar_data *data, void *arg) /* {{{ */ {
228 | msgpack_object *obj = (msgpack_object *)data;
229 |
230 | switch (obj->type) {
231 | case MSGPACK_OBJECT_NIL:
232 | *(void **)arg = NULL;
233 | return YAR_DATA_NULL;
234 | case MSGPACK_OBJECT_BOOLEAN:
235 | *(int *)arg = obj->via.boolean;
236 | return YAR_DATA_BOOL;
237 | case MSGPACK_OBJECT_POSITIVE_INTEGER:
238 | *(ulong *)arg = obj->via.u64;
239 | return YAR_DATA_ULONG;
240 | case MSGPACK_OBJECT_NEGATIVE_INTEGER:
241 | *(long *)arg = obj->via.i64;
242 | return YAR_DATA_LONG;
243 | case MSGPACK_OBJECT_DOUBLE:
244 | *(double *)arg = obj->via.dec;
245 | return YAR_DATA_DOUBLE;
246 | case MSGPACK_OBJECT_RAW:
247 | *(const char **)arg = obj->via.raw.ptr;
248 | return YAR_DATA_STRING;
249 | case MSGPACK_OBJECT_ARRAY:
250 | *(const yar_data **)arg = (yar_data *)obj->via.array.ptr;
251 | return YAR_DATA_ARRAY;
252 | case MSGPACK_OBJECT_MAP:
253 | *(const yar_data **)arg = (yar_data *)obj->via.map.ptr;
254 | return YAR_DATA_MAP;
255 | }
256 | return 0;
257 | }
258 | /* }}} */
259 |
260 | int yar_unpack_data_null(const yar_data *data, int *val) /* {{{ */ {
261 | return yar_unpack_data_value(data, &val);
262 | }
263 | /* }}} */
264 |
265 | int yar_unpack_data_bool(const yar_data *data, int *bval) /* {{{ */ {
266 | return yar_unpack_data_value(data, bval);
267 | }
268 | /* }}} */
269 |
270 | int yar_unpack_data_long(const yar_data *data, long *num) /* {{{ */ {
271 | return yar_unpack_data_value(data, num);
272 | }
273 | /* }}} */
274 |
275 | int yar_unpack_data_ulong(const yar_data *data, ulong *num) /* {{{ */ {
276 | return yar_unpack_data_value(data, num);
277 | }
278 | /* }}} */
279 |
280 | int yar_unpack_data_string(const yar_data *data, const char **str) /* {{{ */ {
281 | return yar_unpack_data_value(data, str);
282 | }
283 | /* }}} */
284 |
285 | int yar_unpack_data_array(const yar_data *data, const yar_data **arg) /* {{{ */ {
286 | return yar_unpack_data_value(data, arg);
287 | }
288 | /* }}} */
289 |
290 | int yar_unpack_data_map(const yar_data *data, const yar_data **arg) /* {{{ */ {
291 | return yar_unpack_data_value(data, arg);
292 | }
293 | /* }}} */
294 |
295 | yar_unpack_iterator * yar_unpack_iterator_init(const yar_data *data) /* {{{ */ {
296 | yar_unpack_iterator *it = NULL;
297 |
298 | switch (data->obj.type) {
299 | case MSGPACK_OBJECT_ARRAY:
300 | {
301 | it = malloc(sizeof(yar_unpack_iterator));
302 | it->position = 0;
303 | it->size = data->obj.via.array.size;
304 | it->data = (yar_data *)data->obj.via.array.ptr;
305 | }
306 | break;
307 | case MSGPACK_OBJECT_MAP:
308 | {
309 | it = malloc(sizeof(yar_unpack_iterator));
310 | it->position = 0;
311 | it->size = data->obj.via.map.size * 2; /* kv */
312 | it->data = (yar_data *)data->obj.via.map.ptr;
313 | }
314 | break;
315 | default:
316 | break;
317 | }
318 |
319 | return it;
320 | }
321 | /* }}} */
322 |
323 | void yar_unpack_iterator_reset(yar_unpack_iterator *it) /* {{{ */ {
324 | it->position = 0;
325 | }
326 | /* }}} */
327 |
328 | int yar_unpack_iterator_next(yar_unpack_iterator *it) /* {{{ */ {
329 | if (it->position + 1 < it->size) {
330 | return ++it->position;
331 | }
332 | return 0;
333 | }
334 | /* }}} */
335 |
336 | const yar_data *yar_unpack_iterator_current(yar_unpack_iterator *it) /* {{{ */ {
337 | msgpack_object *obj = (msgpack_object *)it->data;
338 | obj += it->position;
339 | return (yar_data *)obj;
340 | }
341 | /* }}} */
342 |
343 | void yar_unpack_iterator_free(yar_unpack_iterator *it) /* {{{ */ {
344 | free(it);
345 | }
346 | /* }}} */
347 |
348 | void yar_debug_print_data(const yar_data *data, FILE *fp) /* {{{ */ {
349 | msgpack_object_print(fp? fp : stdout, *(msgpack_object *)data);
350 | }
351 | /* }}} */
352 |
353 | /*
354 | * Local variables:
355 | * tab-width: 4
356 | * c-basic-offset: 4
357 | * End:
358 | * vim600: noet sw=4 ts=4 fdm=marker
359 | * vim<600: sw=4 ts=4
360 | */
361 |
--------------------------------------------------------------------------------
/ngx_yar/yar_pack.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Yar - Concurrent RPC Server for PHP, C etc
3 | *
4 | * Copyright (C) 2012-2012 Xinchen Hui
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | #ifndef YAR_PACK_H
20 | #define YAR_PACK_H
21 |
22 | typedef enum _yar_data_type {
23 | YAR_DATA_NULL = 1,
24 | YAR_DATA_BOOL,
25 | YAR_DATA_LONG,
26 | YAR_DATA_ULONG,
27 | YAR_DATA_DOUBLE,
28 | YAR_DATA_STRING,
29 | YAR_DATA_MAP,
30 | YAR_DATA_ARRAY
31 | } yar_data_type;
32 |
33 | typedef struct _yar_packager yar_packager;
34 | typedef struct _yar_unpackager yar_unpackager;
35 | typedef struct _yar_unpack_iterator yar_unpack_iterator;
36 | typedef struct _yar_data yar_data;
37 |
38 | #define yar_pack_start_null() yar_pack_start(YAR_DATA_NULL, 0)
39 | #define yar_pack_start_bool() yar_pack_start(YAR_DATA_BOOL, 0)
40 | #define yar_pack_start_long() yar_pack_start(YAR_DATA_LONG, 0)
41 | #define yar_pack_start_ulong() yar_pack_start(YAR_DATA_ULONG, 0)
42 | #define yar_pack_start_double() yar_pack_start(YAR_DATA_DOUBLE, 0)
43 | #define yar_pack_start_string() yar_pack_start(YAR_DATA_STRING, 0)
44 | #define yar_pack_start_map(size) yar_pack_start(YAR_DATA_MAP, size)
45 | #define yar_pack_start_array(size) yar_pack_start(YAR_DATA_ARRAY, size)
46 |
47 | /* serialization */
48 | yar_packager * yar_pack_start(yar_data_type type, uint size);
49 | int yar_pack_push_array(yar_packager *packager, uint size);
50 | int yar_pack_push_map(yar_packager *packager, uint size);
51 | int yar_pack_push_null(yar_packager *packager);
52 | int yar_pack_push_bool(yar_packager *packager, int val);
53 | int yar_pack_push_long(yar_packager *packager, long num);
54 | int yar_pack_push_ulong(yar_packager *packager, ulong num);
55 | int yar_pack_push_double(yar_packager *packager, double num);
56 | int yar_pack_push_string(yar_packager *packager, char *str, uint len);
57 | int yar_pack_push_data(yar_packager *packager, const yar_data *data);
58 | int yar_pack_push_packager(yar_packager *packager, yar_packager *data);
59 | int yar_pack_to_string(yar_packager *packager, yar_payload *payload);
60 | void yar_pack_free(yar_packager *packager);
61 |
62 | /* deserialization */
63 | void yar_unpack_free(yar_unpackager *unpk);
64 | yar_unpackager * yar_unpack_init(char *data, uint len);
65 | const yar_data * yar_unpack_unpack(yar_unpackager *unpk);
66 |
67 | yar_data_type yar_unpack_data_type(const yar_data *data, uint *size);
68 | int yar_unpack_data_value(const yar_data *data, void *arg);
69 | int yar_unpack_data_null(const yar_data *data, int *val);
70 | int yar_unpack_data_bool(const yar_data *data, int *bval);
71 | int yar_unpack_data_long(const yar_data *data, long *num);
72 | int yar_unpack_data_ulong(const yar_data *data, ulong *num);
73 | int yar_unpack_data_string(const yar_data *data, const char **str);
74 | int yar_unpack_data_array(const yar_data *data, const yar_data **arg);
75 | int yar_unpack_data_map(const yar_data *data, const yar_data **arg);
76 |
77 | yar_unpack_iterator * yar_unpack_iterator_init(const yar_data *data);
78 | void yar_unpack_iterator_reset(yar_unpack_iterator *it);
79 | int yar_unpack_iterator_next(yar_unpack_iterator *it);
80 | const yar_data *yar_unpack_iterator_current(yar_unpack_iterator *it);
81 | void yar_unpack_iterator_free(yar_unpack_iterator *it);
82 |
83 | void yar_debug_print_data(const yar_data *data, FILE *fp);
84 |
85 | #endif
86 |
87 | /*
88 | * Local variables:
89 | * tab-width: 4
90 | * c-basic-offset: 4
91 | * End:
92 | * vim600: noet sw=4 ts=4 fdm=marker
93 | * vim<600: sw=4 ts=4
94 | */
95 |
--------------------------------------------------------------------------------
/ngx_yar/yar_protocol.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Yar - Concurrent RPC Server for PHP, C etc
3 | *
4 | * Copyright (C) 2012-2012 Xinchen Hui
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | #include
20 | #include /* for htonl */
21 |
22 | #include "yar_common.h"
23 | #include "yar_protocol.h"
24 |
25 | char YAR_PACKAGER[8] = "MSGPACK";
26 |
27 | void yar_protocol_render(yar_header *header, uint id, char *provider, char *token, int body_len, uint reserved) /* {{{ */ {
28 | header->magic_num = htonl(YAR_PROTOCOL_MAGIC_NUM);
29 | header->id = htonl(id);
30 | header->body_len = htonl(body_len);
31 | header->reserved = htonl(reserved);
32 | if (provider) {
33 | memcpy(header->provider, provider, 16);
34 | }
35 | if (token) {
36 | memcpy(header->token, token, 16);
37 | }
38 | return;
39 | } /* }}} */
40 |
41 | int yar_protocol_parse(yar_header *header) /* {{{ */ {
42 |
43 | header->magic_num = ntohl(header->magic_num);
44 |
45 |
46 |
47 | if (header->magic_num != YAR_PROTOCOL_MAGIC_NUM) {
48 | return 0;
49 | }
50 |
51 | header->id = header->id;
52 | header->body_len = header->body_len;
53 | header->reserved = header->reserved;
54 |
55 | return 1;
56 | } /* }}} */
57 |
58 | /*
59 | * Local variables:
60 | * tab-width: 4
61 | * c-basic-offset: 4
62 | * End:
63 | * vim600: noet sw=4 ts=4 fdm=marker
64 | * vim<600: sw=4 ts=4
65 | */
66 |
--------------------------------------------------------------------------------
/ngx_yar/yar_protocol.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Yar - Concurrent RPC Server for PHP, C etc
3 | *
4 | * Copyright (C) 2012-2012 Xinchen Hui
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | #ifndef YAR_PROTOCOL_H
20 | #define YAR_PROTOCOL_H
21 |
22 | #define YAR_PROTOCOL_PERSISTENT 0x1
23 | #define YAR_PROTOCOL_PING 0x2
24 | #define YAR_PROTOCOL_LIST 0x4
25 |
26 | #define YAR_PROTOCOL_MAGIC_NUM 0x80DFEC60
27 | typedef struct _yar_header {
28 | unsigned int id;
29 | unsigned short version;
30 | unsigned int magic_num;
31 | unsigned int reserved;
32 | unsigned char provider[32];
33 | unsigned char token[32];
34 | unsigned int body_len;
35 | } __attribute__ ((packed)) yar_header;
36 |
37 | extern char YAR_PACKAGER[8];
38 |
39 |
40 | void yar_protocol_render(yar_header *header, uint id, char *provider, char *token, int body_len, uint reserved);
41 | int yar_protocol_parse(yar_header *header);
42 | #endif
43 | /*
44 | * Local variables:
45 | * tab-width: 4
46 | * c-basic-offset: 4
47 | * End:
48 | * vim600: noet sw=4 ts=4 fdm=marker
49 | * vim<600: sw=4 ts=4
50 | */
51 |
--------------------------------------------------------------------------------
/ngx_yar/yar_request.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Yar - Concurrent RPC Server for PHP, C etc
3 | *
4 | * Copyright (C) 2012-2012 Xinchen Hui
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | #include
20 | #include "msgpack.h"
21 |
22 | #include "yar_common.h"
23 | #include "yar_pack.h"
24 | #include "yar_request.h"
25 |
26 | static char yar_request_keys[] = {'i', 'm', 'p'};
27 |
28 | int yar_request_pack(yar_request *request, yar_payload *payload, int extra_bytes) /* {{{ */ {
29 | uint index;
30 | yar_packager *pk = yar_pack_start_map(3);
31 |
32 | for (index = 0; index < (sizeof(yar_request_keys) / sizeof(char)); index++) {
33 | switch (yar_request_keys[index]) {
34 | case 'i':
35 | yar_pack_push_string(pk, "i", 1);
36 | yar_pack_push_ulong(pk, request->id);
37 | break;
38 | case 'm':
39 | yar_pack_push_string(pk, "m", 1);
40 | yar_pack_push_string(pk, request->method, request->mlen);
41 | break;
42 | case 'p':
43 | {
44 | yar_packager *packager = (yar_packager *)request->out;
45 |
46 | yar_pack_push_string(pk, "p", 1);
47 | if (packager) {
48 | yar_pack_push_packager(pk, packager);
49 | } else {
50 | yar_pack_push_null(pk);
51 | }
52 | }
53 | break;
54 | default:
55 | continue;
56 | break;
57 | }
58 | }
59 |
60 | {
61 | yar_payload tmp;
62 | yar_pack_to_string(pk, &tmp);
63 | payload->data = malloc(tmp.size + extra_bytes);
64 | memcpy(payload->data + extra_bytes, tmp.data, tmp.size);
65 | payload->size = tmp.size + extra_bytes;
66 | }
67 |
68 | yar_pack_free(pk);
69 |
70 | return 1;
71 | }
72 | /* }}} */
73 |
74 | int yar_request_unpack(yar_request *request, char *payload, uint len, int extra_bytes) /* {{{ */ {
75 | uint size;
76 | const yar_data *obj;
77 | yar_unpackager *unpk = yar_unpack_init(payload + extra_bytes, len - extra_bytes);
78 |
79 | if (!unpk) {
80 | return 0;
81 | }
82 |
83 | request->buffer = (void *)unpk;
84 |
85 | obj = yar_unpack_unpack(unpk);
86 | if (yar_unpack_data_type(obj, &size) != YAR_DATA_MAP || size < 2) {
87 | return 0;
88 | } else {
89 | yar_unpack_iterator *it = yar_unpack_iterator_init(obj);
90 | do {
91 | const char *key;
92 | obj = yar_unpack_iterator_current(it);
93 | if (yar_unpack_data_type(obj, &size) != YAR_DATA_STRING) {
94 | yar_unpack_iterator_free(it);
95 | return 0;
96 | }
97 | yar_unpack_data_string(obj, &key);
98 | /* fetch value */
99 | if (!yar_unpack_iterator_next(it)) {
100 | yar_unpack_iterator_free(it);
101 | return 0;
102 | }
103 | obj = yar_unpack_iterator_current(it);
104 | if (strncmp(key, "i", sizeof("i") - 1) == 0) {
105 | if (yar_unpack_data_type(obj, &size) == YAR_DATA_ULONG) {
106 | ulong id;
107 | yar_unpack_data_ulong(obj, &id);
108 | request->id = id;
109 | }
110 | } else if (strncmp(key, "m", sizeof("m") - 1) == 0) {
111 | if (yar_unpack_data_type(obj, &size) == YAR_DATA_STRING) {
112 | const char *method;
113 | yar_unpack_data_string(obj, &method);
114 | request->method = malloc(size);
115 | memcpy(request->method, method, size);
116 | request->mlen = size;
117 | }
118 | } else if (strncmp(key, "p", sizeof("p") - 1) == 0) {
119 | request->in = (void *)obj;
120 | } else {
121 | continue;
122 | }
123 | } while (yar_unpack_iterator_next(it));
124 | yar_unpack_iterator_free(it);
125 | }
126 |
127 | return 1;
128 | }
129 | /* }}} */
130 |
131 | void yar_request_set_parameters(yar_request *request, yar_packager *packager) /* {{{ */ {
132 | if (request->out) {
133 | yar_pack_free((yar_packager *)request->out);
134 | }
135 | request->out = yar_pack_start_null();
136 | yar_pack_push_packager((yar_packager *)request->out, packager);
137 | }
138 | /* }}} */
139 |
140 | const yar_data * yar_request_get_parameters(yar_request *request) /* {{{ */ {
141 | return request->in;
142 | }
143 | /* }}} */
144 |
145 | void yar_request_free(yar_request *request) /* {{{ */ {
146 | if (request->method) {
147 | free(request->method);
148 | }
149 | if (request->out) {
150 | yar_pack_free((yar_packager *)request->out);
151 | }
152 | if (request->buffer) {
153 | yar_unpack_free((yar_unpackager *)request->buffer);
154 | }
155 | if (request->body) {
156 | free(request->body);
157 | }
158 | }
159 | /* }}} */
160 |
161 | /*
162 | * Local variables:
163 | * tab-width: 4
164 | * c-basic-offset: 4
165 | * End:
166 | * vim600: noet sw=4 ts=4 fdm=marker
167 | * vim<600: sw=4 ts=4
168 | */
169 |
--------------------------------------------------------------------------------
/ngx_yar/yar_request.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Yar - Concurrent RPC Server for PHP, C etc
3 | *
4 | * Copyright (C) 2012-2012 Xinchen Hui
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | #ifndef YAR_REQUEST_H
20 | #define YAR_REQUEST_H
21 |
22 | typedef struct _yar_request {
23 | ulong id;
24 | char *method;
25 | uint mlen;
26 | void *out;
27 | void *buffer;
28 | yar_data *in;
29 | size_t size;
30 | size_t blen;
31 | char *body;
32 | } yar_request;
33 |
34 | int yar_request_pack(yar_request *request, struct _yar_payload *payload, int extra_bytes);
35 | int yar_request_unpack(yar_request *request, char *payload, uint len, int extra_bytes);
36 | void yar_request_set_parameters(yar_request *request, yar_packager *packager);
37 | const yar_data * yar_request_get_parameters(yar_request *request);
38 | void yar_request_free(yar_request *request);
39 |
40 | #endif
41 |
42 | /*
43 | * Local variables:
44 | * tab-width: 4
45 | * c-basic-offset: 4
46 | * End:
47 | * vim600: noet sw=4 ts=4 fdm=marker
48 | * vim<600: sw=4 ts=4
49 | */
50 |
--------------------------------------------------------------------------------
/ngx_yar/yar_response.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Yar - Concurrent RPC Server for PHP, C etc
3 | *
4 | * Copyright (C) 2012-2012 Xinchen Hui
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | #include
20 | #include /* for va_list */
21 | #include
22 | #include "msgpack.h"
23 |
24 | #include "yar_common.h"
25 | #include "yar_pack.h"
26 | #include "yar_protocol.h"
27 | #include "yar_response.h"
28 |
29 | static char yar_response_keys[] = {'i', 's', 'r', 'e'};
30 |
31 | int yar_response_pack(yar_response *response, yar_payload *payload, int extra_bytes) /* {{{ */ {
32 | uint index;
33 | yar_packager *pk = yar_pack_start_map(4);
34 |
35 | for (index = 0; index < (sizeof(yar_response_keys) / sizeof(char)); index++) {
36 | switch (yar_response_keys[index]) {
37 | case 'i':
38 | yar_pack_push_string(pk, "i", 1);
39 | yar_pack_push_ulong(pk, response->id);
40 | break;
41 | case 's':
42 | yar_pack_push_string(pk, "s", 1);
43 | yar_pack_push_long(pk, response->status);
44 | break;
45 | case 'r':
46 | {
47 | yar_packager *packager = response->out;
48 | yar_pack_push_string(pk, "r", 1);
49 | if (packager) {
50 | yar_pack_push_packager(pk, packager);
51 | } else {
52 | yar_pack_push_null(pk);
53 | }
54 | }
55 | break;
56 | case 'e':
57 | yar_pack_push_string(pk, "e", 1);
58 | if (response->error) {
59 | yar_pack_push_string(pk, response->error, response->elen);
60 | } else {
61 | yar_pack_push_null(pk);
62 | }
63 | break;
64 | default:
65 | break;
66 | }
67 | }
68 |
69 | {
70 | yar_payload tmp;
71 | yar_pack_to_string(pk, &tmp);
72 | payload->data = malloc(tmp.size + extra_bytes);
73 | memcpy(payload->data + extra_bytes, tmp.data, tmp.size);
74 | payload->size = tmp.size + extra_bytes;
75 | }
76 |
77 | yar_pack_free(pk);
78 |
79 | return 1;
80 | }
81 | /* }}} */
82 |
83 |
84 | int yar_response_unpack(yar_response *response, char *payload, uint len, int extra_bytes) /* {{{ */ {
85 | uint size;
86 | const yar_data *obj;
87 | yar_unpackager *unpk = yar_unpack_init(payload + extra_bytes, len - extra_bytes);
88 |
89 | if (!unpk) {
90 | return 0;
91 | }
92 |
93 | response->buffer = (void *)unpk;
94 |
95 | obj = yar_unpack_unpack(unpk);
96 | if (yar_unpack_data_type(obj, &size) != YAR_DATA_MAP || size < 2) {
97 | return 0;
98 | } else {
99 | yar_unpack_iterator *it = yar_unpack_iterator_init(obj);
100 | do {
101 | const char *key;
102 | obj = yar_unpack_iterator_current(it);
103 | if (yar_unpack_data_type(obj, &size) != YAR_DATA_STRING) {
104 | yar_unpack_iterator_free(it);
105 | return 0;
106 | }
107 | yar_unpack_data_string(obj, &key);
108 | /* fetch value */
109 | if (!yar_unpack_iterator_next(it)) {
110 | yar_unpack_iterator_free(it);
111 | return 0;
112 | }
113 | obj = yar_unpack_iterator_current(it);
114 | if (strncmp(key, "i", sizeof("i") - 1) == 0) {
115 | if (yar_unpack_data_type(obj, &size) == YAR_DATA_ULONG) {
116 | ulong id;
117 | yar_unpack_data_ulong(obj, &id);
118 | response->id = id;
119 | }
120 | } else if (strncmp(key, "s", sizeof("s") - 1) == 0) {
121 | if (yar_unpack_data_type(obj, &size) == YAR_DATA_ULONG) {
122 | long status;
123 | yar_unpack_data_long(obj, &status);
124 | response->status = status;
125 | }
126 | } else if (strncmp(key, "e", sizeof("e") - 1) == 0) {
127 | if (yar_unpack_data_type(obj, &size) == YAR_DATA_STRING) {
128 | const char *errmsg;
129 | yar_unpack_data_string(obj, &errmsg);
130 | response->error = malloc(size);
131 | memcpy(response->error, errmsg, size);
132 | response->elen = size;
133 | }
134 | } else if (strncmp(key, "r", sizeof("r") - 1) == 0) {
135 | response->in = (void *)obj;
136 | } else {
137 | continue;
138 | }
139 | } while (yar_unpack_iterator_next(it));
140 | yar_unpack_iterator_free(it);
141 | }
142 |
143 | return 1;
144 | }
145 | /* }}} */
146 |
147 | void yar_response_set_error(yar_response *response, int code, const char *fmt, ...) /* {{{ */ {
148 | va_list args;
149 | uint len;
150 | char buf[1024];
151 |
152 | va_start(args, fmt);
153 | len = vsnprintf(buf, sizeof(buf), fmt, args);
154 | va_end(args);
155 | if (len >= sizeof(buf)) {
156 | memcpy(buf + sizeof(buf) - sizeof("..."), "...", sizeof("...") - 1);
157 | len = sizeof(buf) - 1;
158 | }
159 |
160 | response->status = code;
161 | response->error = malloc(len);
162 | memcpy(response->error, buf, len);
163 | response->elen = len;
164 | }
165 | /* }}} */
166 |
167 | void yar_response_set_retval(yar_response *response, yar_packager *packager) /* {{{ */ {
168 | if (response->out) {
169 | yar_pack_free((yar_packager *)response->out);
170 | }
171 | response->out = yar_pack_start_null();
172 | yar_pack_push_packager((yar_packager *)response->out, packager);
173 | }
174 | /* }}} */
175 |
176 | const yar_data * yar_response_get_response(yar_response *response) /* {{{ */ {
177 | return (const yar_data *)response->in;
178 | }
179 | /* }}} */
180 |
181 | int yar_response_get_status(yar_response *response) /* {{{ */ {
182 | return response->status;
183 | }
184 | /* }}} */
185 |
186 | int yar_response_get_error(yar_response *response, const char **msg, uint *len) /* {{{ */ {
187 | if (!response->elen) {
188 | return 0;
189 | }
190 |
191 | *msg = response->error;
192 | *len = response->elen;
193 | return 1;
194 | }
195 | /* }}} */
196 |
197 | void yar_response_free(yar_response *response) /* {{{ */ {
198 | if (response->payload.data) {
199 | free(response->payload.data);
200 | }
201 | if (response->error) {
202 | free(response->error);
203 | }
204 | if (response->out) {
205 | yar_pack_free((yar_packager *)response->out);
206 | }
207 | if (response->buffer) {
208 | yar_unpack_free((yar_unpackager *)response->buffer);
209 | }
210 | }
211 | /*}}}*/
212 |
213 | /*
214 | * Local variables:
215 | * tab-width: 4
216 | * c-basic-offset: 4
217 | * End:
218 | * vim600: noet sw=4 ts=4 fdm=marker
219 | * vim<600: sw=4 ts=4
220 | */
221 |
--------------------------------------------------------------------------------
/ngx_yar/yar_response.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Yar - Concurrent RPC Server for PHP, C etc
3 | *
4 | * Copyright (C) 2012-2012 Xinchen Hui
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | #ifndef YAR_RESPONSE_H
20 | #define YAR_RESPONSE_H
21 |
22 | typedef struct _yar_response {
23 | long id;
24 | int status;
25 | char *error;
26 | uint elen;
27 | yar_data *in;
28 | struct _yar_payload payload; /* do not manipulate following elements */
29 | void *out;
30 | void *buffer;
31 | } yar_response;
32 |
33 | void yar_response_set_retval(yar_response *response, yar_packager *packager);
34 | void yar_response_set_error(yar_response *response, int code, const char *fmt, ...);
35 | const yar_data * yar_response_get_response(yar_response *response);
36 | int yar_response_get_status(yar_response *response);
37 | int yar_response_get_error(yar_response *response, const char **msg, uint *len);
38 |
39 | int yar_response_pack(yar_response *response, struct _yar_payload *payload, int extra_bytes);
40 | int yar_response_unpack(yar_response *response, char *payload, uint len, int extra_bytes);
41 | void yar_response_free(yar_response *response);
42 |
43 | #endif
44 |
45 | /*
46 | * Local variables:
47 | * tab-width: 4
48 | * c-basic-offset: 4
49 | * End:
50 | * vim600: noet sw=4 ts=4 fdm=marker
51 | * vim<600: sw=4 ts=4
52 | */
53 |
--------------------------------------------------------------------------------
/php_tests/config.php:
--------------------------------------------------------------------------------
1 | 'http://yar.local.com'
6 |
7 | );
8 |
9 |
--------------------------------------------------------------------------------
/php_tests/test1.php:
--------------------------------------------------------------------------------
1 | setOpt(YAR_OPT_PACKAGER,"MSGPACK");
11 | var_dump($client->test());
12 | }catch(Exception $e){
13 |
14 | echo $e->getMessage();
15 | }
16 |
17 | try{
18 | $client = new Yar_Client($config['host']);
19 | $client->setOpt(YAR_OPT_PACKAGER,"MSGPACK");
20 |
21 | var_dump($client->echo(array("a"=>"b")));
22 | }catch(Exception $e){
23 | echo $e->getMessage();
24 | }
25 |
26 | try{
27 | $client = new Yar_Client($config['host']);
28 | $client->setOpt(YAR_OPT_PACKAGER,"MSGPACK");
29 |
30 | //var_dump($client->test3());
31 | }catch(Exception $e){
32 |
33 | echo $e->getMessage();
34 | }
35 |
--------------------------------------------------------------------------------
/src/ngx_yar_module_def.h:
--------------------------------------------------------------------------------
1 | #ifndef __ngx_yar_module_def_H_
2 | #define __ngx_yar_module_def_H_
3 |
4 | #endif //ngx_yar_module_def_H_
5 |
--------------------------------------------------------------------------------
/src/ngx_yar_module_handler.c:
--------------------------------------------------------------------------------
1 | #include "ngx_yar_module_handler.h"
2 | #include "ngx_yar_module_impl.h"
3 | #include
4 | #include
5 |
6 | static void* ngx_http_yar_create_loc_conf(ngx_conf_t *cf);
7 |
8 | static char* ngx_http_yar_conf_yar_method_path(ngx_conf_t *cf, ngx_command_t *cmd,void *conf);
9 | static char* ngx_http_yar_conf_yar_bootstrap(ngx_conf_t *cf, ngx_command_t *cmd,void *conf);
10 | static char* ngx_http_yar_conf_yar_finalize(ngx_conf_t *cf, ngx_command_t *cmd,void *conf);
11 | static char* ngx_http_yar_conf_yar_custom_config(ngx_conf_t *cf, ngx_command_t *cmd,void *conf);
12 | static char* ngx_http_yar_conf_on(ngx_conf_t *cf, ngx_command_t *cmd,void *conf);
13 | static char* ngx_http_yar_conf_debug(ngx_conf_t *cf, ngx_command_t *cmd,void *conf);
14 | ngx_int_t ngx_http_yar_read_request_handler(ngx_http_request_t *r);
15 | void ngx_http_yar_handler(ngx_http_request_t *r);
16 |
17 | static ngx_command_t ngx_http_yar_commands[] = {
18 |
19 | {
20 | ngx_string("yar_method_path"),
21 | NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
22 | ngx_http_yar_conf_yar_method_path,
23 | NGX_HTTP_LOC_CONF_OFFSET,
24 | offsetof(ngx_http_yar_loc_conf_t, yar_method_path),
25 | NULL
26 | },
27 |
28 | {
29 | ngx_string("yar_bootstrap"),
30 | NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
31 | ngx_http_yar_conf_yar_bootstrap,
32 | NGX_HTTP_LOC_CONF_OFFSET,
33 | offsetof(ngx_http_yar_loc_conf_t, bootstrap),
34 | NULL
35 | },
36 |
37 | {
38 | ngx_string("yar_finalize"),
39 | NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
40 | ngx_http_yar_conf_yar_finalize,
41 | NGX_HTTP_LOC_CONF_OFFSET,
42 | offsetof(ngx_http_yar_loc_conf_t, finalize),
43 | NULL
44 | },
45 |
46 |
47 |
48 | {
49 | ngx_string("yar_custom_config"),
50 | NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
51 | ngx_http_yar_conf_yar_custom_config,
52 | NGX_HTTP_LOC_CONF_OFFSET,
53 | offsetof(ngx_http_yar_loc_conf_t, custom_config),
54 | NULL
55 | },
56 |
57 |
58 |
59 |
60 | {
61 | ngx_string("yar_method_path"),
62 | NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
63 | ngx_http_yar_conf_yar_method_path,
64 | NGX_HTTP_LOC_CONF_OFFSET,
65 | offsetof(ngx_http_yar_loc_conf_t, yar_method_path),
66 | NULL
67 | },
68 |
69 |
70 | {
71 | ngx_string("yar_on"),
72 | NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS|NGX_CONF_TAKE1,
73 | ngx_http_yar_conf_on,
74 | NGX_HTTP_LOC_CONF_OFFSET,
75 | offsetof(ngx_http_yar_loc_conf_t, on),
76 | NULL
77 | },
78 |
79 | {
80 | ngx_string("yar_debug"),
81 | NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS|NGX_CONF_TAKE1,
82 | ngx_http_yar_conf_debug,
83 | NGX_HTTP_LOC_CONF_OFFSET,
84 | offsetof(ngx_http_yar_loc_conf_t, debug),
85 | NULL
86 | },
87 |
88 | {
89 | ngx_string("yar_slow_timeout"),
90 | NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
91 | ngx_conf_set_num_slot,
92 | NGX_HTTP_LOC_CONF_OFFSET,
93 | offsetof(ngx_http_yar_loc_conf_t, slow_timeout),
94 | NULL
95 | },
96 |
97 |
98 | {
99 | ngx_string("yar_timeout"),
100 | NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
101 | ngx_conf_set_num_slot,
102 | NGX_HTTP_LOC_CONF_OFFSET,
103 | offsetof(ngx_http_yar_loc_conf_t, timeout),
104 | NULL
105 | },
106 |
107 | {
108 | ngx_string("yar_timeout_try_times"),
109 | NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
110 | ngx_conf_set_num_slot,
111 | NGX_HTTP_LOC_CONF_OFFSET,
112 | offsetof(ngx_http_yar_loc_conf_t, timeout_try_times),
113 | NULL
114 | },
115 |
116 |
117 |
118 | ngx_null_command
119 | };
120 |
121 |
122 |
123 | static ngx_http_module_t ngx_http_yar_module_ctx = {
124 | NULL, /* preconfiguration */
125 | NULL, /* postconfiguration */
126 | NULL, /* create main configuration */
127 | NULL, /* init main configuration */
128 |
129 | NULL, /* create server configuration */
130 | NULL, /* merge server configuration */
131 |
132 | ngx_http_yar_create_loc_conf, /* create location configuration */
133 |
134 | NULL /* merge location configuration */
135 | };
136 |
137 | ngx_module_t ngx_http_yar_module = {
138 | NGX_MODULE_V1,
139 | &ngx_http_yar_module_ctx, /* module context */
140 | ngx_http_yar_commands, /* module directives */
141 | NGX_HTTP_MODULE, /* module type */
142 | NULL, /* init master */
143 | NULL, /* init module */
144 | NULL, /* init process */
145 | NULL, /* init thread */
146 | NULL, /* exit thread */
147 | NULL, /* exit process */
148 | NULL, /* exit master */
149 | NGX_MODULE_V1_PADDING
150 | };
151 |
152 | static void *ngx_http_yar_create_loc_conf(ngx_conf_t *cf)
153 | {
154 | ngx_http_yar_loc_conf_t* local_conf = NULL;
155 |
156 | local_conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_yar_loc_conf_t));
157 |
158 | if (local_conf == NULL)
159 | {
160 | return NULL;
161 | }
162 |
163 | ngx_str_null(&local_conf->yar_method_path);
164 |
165 | local_conf->yar_method_handler = NULL;
166 |
167 | local_conf->on = 0;
168 |
169 | local_conf->debug = 0;
170 |
171 | local_conf->slow_timeout = NGX_CONF_UNSET;
172 | local_conf->timeout = NGX_CONF_UNSET;
173 | local_conf->timeout_try_times = NGX_CONF_UNSET;
174 |
175 | return local_conf;
176 | }
177 |
178 | static char* ngx_http_yar_conf_yar_method_path(ngx_conf_t *cf, ngx_command_t *cmd,void *conf){
179 |
180 | ngx_http_yar_loc_conf_t *local_conf = conf;
181 |
182 | char* rv = ngx_conf_set_str_slot(cf, cmd, local_conf);
183 |
184 | if(local_conf->yar_method_path.len > 0 && local_conf->yar_method_handler == NULL){
185 |
186 | local_conf->yar_method_handler = (void *) dlopen ((const char *) local_conf->yar_method_path.data,
187 | RTLD_NOW | RTLD_LOCAL);
188 |
189 | local_conf->dlerror = dlerror();
190 |
191 | }
192 |
193 | return rv;
194 |
195 | }
196 |
197 | static char* ngx_http_yar_conf_yar_bootstrap(ngx_conf_t *cf, ngx_command_t *cmd,void *conf){
198 |
199 | ngx_http_yar_loc_conf_t *local_conf = conf;
200 | char* rv = ngx_conf_set_str_slot(cf, cmd, local_conf);
201 | return rv;
202 |
203 | }
204 |
205 | static char* ngx_http_yar_conf_yar_finalize(ngx_conf_t *cf, ngx_command_t *cmd,void *conf){
206 |
207 | ngx_http_yar_loc_conf_t *local_conf = conf;
208 |
209 | char* rv = ngx_conf_set_str_slot(cf, cmd, local_conf);
210 |
211 | return rv;
212 |
213 | }
214 |
215 | static char* ngx_http_yar_conf_yar_custom_config(ngx_conf_t *cf, ngx_command_t *cmd,void *conf){
216 |
217 | ngx_http_yar_loc_conf_t *local_conf = conf;
218 | char* rv = ngx_conf_set_str_slot(cf, cmd, local_conf);
219 | return rv;
220 |
221 | }
222 |
223 |
224 | static char* ngx_http_yar_conf_on(ngx_conf_t *cf, ngx_command_t *cmd,void *conf){
225 |
226 | ngx_http_yar_loc_conf_t *local_conf = conf;
227 |
228 | local_conf->on = 1;
229 |
230 | ngx_http_core_loc_conf_t *clcf;
231 |
232 | clcf = ngx_http_conf_get_module_loc_conf (cf, ngx_http_core_module);
233 |
234 | clcf->handler = ngx_http_yar_read_request_handler;
235 |
236 | return NULL;
237 | }
238 |
239 | static char* ngx_http_yar_conf_debug(ngx_conf_t *cf, ngx_command_t *cmd,void *conf){
240 |
241 | ngx_http_yar_loc_conf_t *local_conf = conf;
242 |
243 | local_conf->debug = 1;
244 |
245 | return NULL;
246 | }
247 |
248 |
249 |
250 | void ngx_http_yar_handler(ngx_http_request_t *r){
251 |
252 | ngx_str_t error;
253 |
254 | ngx_str_t *client_request_body = ngx_http_yar_read_client_post_body(r);
255 |
256 | yar_request *request = NULL;
257 |
258 | yar_response *response = NULL;
259 |
260 |
261 |
262 | if(!client_request_body || client_request_body->len < sizeof(yar_header)){
263 |
264 | ngx_str_set(&error,"read request body error.");
265 |
266 | goto send_error;
267 |
268 | }
269 |
270 | request = ngx_http_yar_get_yar_request(r,client_request_body);
271 |
272 | if(!request){
273 |
274 | ngx_str_set(&error,"parse yar protocol error.");
275 |
276 | goto send_error;
277 |
278 | }
279 |
280 | if(request->mlen < 1){
281 |
282 | ngx_str_set(&error,"call undefined method.");
283 |
284 | goto send_error;
285 |
286 | }
287 |
288 | response = ngx_http_yar_get_yar_response(r,request);
289 |
290 | if(!response){
291 |
292 | ngx_str_set(&error,"get response error.");
293 |
294 | goto send_error;
295 |
296 | }
297 |
298 | if (!yar_response_pack(response, &(response->payload), sizeof(yar_header) + sizeof(YAR_PACKAGER))) {
299 |
300 | ngx_str_set(&error,"protocol pack response error.");
301 |
302 | goto send_error;
303 |
304 | }
305 |
306 |
307 | yar_header response_header;
308 |
309 | yar_protocol_render(&response_header, request->id, NULL, NULL, response->payload.size - sizeof(yar_header), 0);
310 |
311 | memcpy(response->payload.data, (char *)&response_header, sizeof(yar_header));
312 |
313 | memcpy(response->payload.data + sizeof(yar_header), YAR_PACKAGER, sizeof(YAR_PACKAGER));
314 |
315 | ngx_str_t *reply = ngx_pcalloc (r->pool, sizeof (ngx_str_t));
316 |
317 | u_char *data = ngx_pcalloc (r->pool, sizeof (u_char) * response->payload.size);
318 |
319 | reply->len = response->payload.size;
320 |
321 | memcpy(data,response->payload.data,response->payload.size);
322 |
323 | reply->data = data;
324 |
325 | ngx_http_yar_send_response(r,reply);
326 |
327 | goto clean_resource;
328 |
329 | while(0){
330 |
331 | send_error:
332 | {
333 |
334 | ngx_http_yar_send_response (r, &error);
335 |
336 | goto clean_resource;
337 | };
338 |
339 | return ;
340 |
341 | }
342 |
343 | clean_resource:
344 | {
345 | if (request) {
346 |
347 | yar_request_free (request);
348 |
349 | }
350 |
351 | if (response) {
352 |
353 | yar_response_free (response);
354 |
355 | }
356 | }
357 |
358 | }
359 |
360 |
361 | ngx_int_t ngx_http_yar_read_request_handler(ngx_http_request_t *r){
362 |
363 |
364 | r->request_body_in_single_buf = 1;
365 |
366 | r->request_body_in_file_only = 0;
367 |
368 | ngx_int_t rc;
369 |
370 | rc = ngx_http_read_client_request_body(r,ngx_http_yar_handler);
371 |
372 | if(rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
373 |
374 | return rc;
375 |
376 | }
377 |
378 |
379 |
380 |
381 | return NGX_DONE;
382 | }
383 |
--------------------------------------------------------------------------------
/src/ngx_yar_module_handler.h:
--------------------------------------------------------------------------------
1 | #ifndef __ngx_yar_module_handler_H_
2 | #define __ngx_yar_module_handler_H_
3 | #include
4 | #include
5 | #include
6 |
7 | typedef struct
8 | {
9 |
10 | ngx_str_t yar_method_path; // for yar_method_path="*.so"
11 |
12 | void *yar_method_handler; // for dlopen(yar_method_path)
13 |
14 | ngx_int_t on; // for yar_server=1;
15 |
16 | ngx_int_t debug; // for yar_debug=1;
17 |
18 | ngx_int_t timeout; // for yar_timeout=5;
19 |
20 | ngx_int_t timeout_try_times;
21 |
22 | ngx_int_t slow_timeout; // for yar_slow_timeout = 200 ms
23 |
24 | ngx_str_t custom_config;
25 |
26 | ngx_str_t bootstrap;
27 |
28 | ngx_str_t finalize;
29 |
30 | char * dlerror;
31 |
32 | } ngx_http_yar_loc_conf_t;
33 |
34 |
35 | ngx_module_t* ngx_http_yar_get_module();
36 |
37 | #endif //ngx_yar_module_handler_H_
38 |
--------------------------------------------------------------------------------
/src/ngx_yar_module_impl.c:
--------------------------------------------------------------------------------
1 | #include "ngx_yar_module_impl.h"
2 | #include "ngx_yar_module_handler.h"
3 | #include
4 | #include
5 |
6 |
7 | typedef void (*yar_bootstrap_method)(void *config,uint config_len);
8 |
9 | typedef void (*yar_finalize_method)(yar_request *request, yar_response *response);
10 |
11 | extern ngx_module_t ngx_http_yar_module;
12 |
13 | ngx_str_t* ngx_http_yar_read_client_post_body(ngx_http_request_t *r){
14 |
15 | u_char *p;
16 | u_char *data = NULL;
17 | size_t len = 0;
18 | ngx_buf_t *buf, *next;
19 | ngx_chain_t *cl;
20 |
21 | if(r->request_body == NULL || r->request_body->bufs == NULL){
22 |
23 | ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
24 | "read client request body error.");
25 |
26 | return NULL;
27 | }
28 |
29 | cl = r->request_body->bufs;
30 |
31 | buf = cl->buf;
32 |
33 | if (cl->next == NULL) {
34 |
35 | len = (buf->last - buf->pos);
36 |
37 | p = ngx_pnalloc(r->pool, len + 1);
38 |
39 | if (p == NULL) {
40 |
41 | }
42 |
43 | data = p;
44 |
45 | ngx_memcpy(p, buf->pos, len);
46 |
47 | data[len] = 0;
48 |
49 | } else {
50 |
51 | next = cl->next->buf;
52 |
53 | len = (buf->last - buf->pos) + (next->last - next->pos);
54 |
55 | p = ngx_pnalloc(r->pool, len + 1);
56 |
57 | data = p;
58 |
59 | if (p == NULL) {
60 |
61 | }
62 |
63 | p = ngx_cpymem(p, buf->pos, buf->last - buf->pos);
64 |
65 | ngx_memcpy(p, next->pos, next->last - next->pos);
66 |
67 | data[len] = 0;
68 |
69 | }
70 |
71 | ngx_str_t *body = (ngx_str_t *)ngx_pnalloc(r->pool,sizeof(ngx_str_t));
72 |
73 | body->len = len;
74 |
75 | body->data = data;
76 |
77 | return body;
78 |
79 |
80 | }
81 |
82 | yar_request* ngx_http_yar_get_yar_request(ngx_http_request_t *r,ngx_str_t *body){
83 |
84 | unsigned int protocol_len = sizeof(yar_header) + sizeof(YAR_PACKAGER);
85 |
86 | if(!body || body->len < protocol_len) {
87 |
88 | return NULL;
89 | }
90 |
91 | yar_header *header = (yar_header *)body->data;
92 |
93 | int ret = yar_protocol_parse(header);
94 |
95 | if(!ret) return NULL;
96 |
97 | if(ngx_strncmp (body->data + sizeof(yar_header),YAR_PACKAGER,sizeof(YAR_PACKAGER) - 1) != 0 ){
98 |
99 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
100 | "not support packager name(%s). only support for MSGPACK",body->data + sizeof(yar_header));
101 | return NULL;
102 | }
103 |
104 | ngx_str_t protocol_body = ngx_null_string;
105 |
106 | protocol_body.data = body->data + protocol_len;
107 |
108 | protocol_body.len = body->len - protocol_len;
109 |
110 | yar_request *request = (yar_request *)ngx_pnalloc(r->pool,sizeof(yar_request));
111 |
112 | memset(request,0,sizeof(yar_request));
113 |
114 | request->id = 0;
115 |
116 | request->mlen = 0;
117 |
118 | request->body = NULL;
119 |
120 | ret = yar_request_unpack (request,(char *)protocol_body.data,header->body_len,0);
121 |
122 | if(!ret){
123 |
124 | ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
125 | "unpack yar request error.");
126 |
127 | return NULL;
128 |
129 | }
130 |
131 | if(request->mlen < 1) {
132 |
133 | ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
134 | "yar call method name cannt be empty.");
135 |
136 | return NULL;
137 | }
138 |
139 | return request;
140 |
141 |
142 | }
143 |
144 | yar_response* ngx_http_yar_get_yar_response(ngx_http_request_t *r, yar_request *request){
145 |
146 | if(!r || !request) return NULL;
147 |
148 | if(!request->id || !request->mlen || !request->method) return NULL;
149 |
150 | if(request->mlen > 256) return NULL;
151 |
152 | char method[256] = {0};
153 |
154 | memcpy(method,request->method,request->mlen);
155 | method[request->mlen] = 0;
156 |
157 | ngx_http_yar_loc_conf_t* my_conf = ngx_http_get_module_loc_conf(r, ngx_http_yar_module);
158 |
159 | if(!my_conf->yar_method_handler){
160 | ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
161 | "cannt open yar_method_path(%s):dlerror:%s",(char *)my_conf->yar_method_path.data,my_conf->dlerror);
162 |
163 | return NULL;
164 |
165 | }
166 |
167 | yar_response *response = (yar_response *)ngx_pnalloc(r->pool,sizeof(yar_response));
168 |
169 | memset((yar_response *)response,0,sizeof(yar_response));
170 |
171 | response->id = 0;
172 |
173 | response->out = NULL;
174 |
175 | response->payload.size = 0;
176 |
177 | response->payload.data = NULL;
178 |
179 | char *cookie = NULL;
180 |
181 | char real_method[256] = {0};
182 |
183 |
184 | sprintf (real_method,"yar_method_%s",method);
185 |
186 | yar_method current_method = (yar_method)dlsym(my_conf->yar_method_handler,real_method);
187 |
188 | if(!current_method) {
189 |
190 | ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
191 | "yar call undefined method %s.",method);
192 |
193 | yar_response_free((yar_response *)response);
194 |
195 | return NULL;
196 | }
197 |
198 |
199 | struct timeval start;
200 | struct timeval end;
201 |
202 | gettimeofday(&start, NULL);
203 |
204 |
205 | char bootstrap_method[256] = {0};
206 |
207 | if(my_conf->bootstrap.len > 0){
208 |
209 | memcpy(bootstrap_method,my_conf->bootstrap.data,my_conf->bootstrap.len);
210 |
211 | bootstrap_method[my_conf->bootstrap.len] = 0;
212 |
213 | yar_bootstrap_method bootstrap = (yar_bootstrap_method)dlsym(my_conf->yar_method_handler,bootstrap_method);
214 |
215 | if(bootstrap){
216 |
217 | bootstrap(my_conf->custom_config.data,my_conf->custom_config.len);
218 |
219 | }else{
220 |
221 | }
222 |
223 | }
224 |
225 | /**
226 | * todo:i will be implement yar_timeout with current_method run as long time.
227 | */
228 |
229 | current_method((yar_request *)request,(yar_response *)response,cookie);
230 |
231 | char finalize_method[256] = {0};
232 |
233 | if(my_conf->finalize.len > 0){
234 |
235 | memcpy(finalize_method,my_conf->finalize.data,my_conf->finalize.len);
236 |
237 | finalize_method[my_conf->finalize.len] = 0;
238 |
239 | }
240 |
241 | yar_finalize_method finalize = (yar_finalize_method)dlsym(my_conf->yar_method_handler,finalize_method);
242 |
243 | if(finalize){
244 |
245 | finalize((yar_request *)request,(yar_response *)response);
246 |
247 | }
248 |
249 | gettimeofday(&end, NULL);
250 |
251 |
252 | int used_sec = end.tv_sec - start.tv_sec;
253 | int used_usec = end.tv_usec - start.tv_usec;
254 |
255 | float used_msec = ((float)(used_sec * 1000 * 1000) +used_usec) / 1000;
256 |
257 | if(my_conf->slow_timeout > 0 && used_msec > my_conf->slow_timeout){
258 |
259 | ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
260 | "yar call method %s too slow. [%.3f ms]",method,used_msec);
261 |
262 | }else{
263 |
264 | ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
265 | "yar call method %s. [%.3f ms]",method,used_msec);
266 |
267 | }
268 |
269 | return (yar_response *)response;
270 |
271 | }
272 |
273 |
274 | ngx_int_t ngx_http_yar_send_response(ngx_http_request_t *r, ngx_str_t *reply){
275 |
276 | ngx_buf_t *b = NULL;
277 |
278 | ngx_chain_t *out = ngx_pcalloc (r->pool, sizeof (ngx_chain_t));;
279 |
280 | ngx_uint_t content_length = reply->len;
281 |
282 | ngx_str_set (&r->headers_out.content_type, "application/msgpack");
283 |
284 | b = ngx_create_temp_buf(r->pool, content_length);
285 | memcpy(b->pos,reply->data,content_length);
286 | b->last = b->pos + content_length;
287 | b->last_buf = 1;
288 |
289 | out->buf = b;
290 |
291 | out->next = NULL;
292 |
293 | r->headers_out.status = NGX_HTTP_OK;
294 |
295 | r->headers_out.content_length_n = content_length;
296 |
297 | ngx_http_send_header (r);
298 |
299 | int rc = ngx_http_output_filter (r, out);
300 |
301 | ngx_http_finalize_request (r, rc);
302 |
303 | return rc;
304 |
305 |
306 | }
--------------------------------------------------------------------------------
/src/ngx_yar_module_impl.h:
--------------------------------------------------------------------------------
1 | #ifndef __ngx_yar_module_impl_H_
2 | #define __ngx_yar_module_impl_H_
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include "ngx_yar_module_handler.h"
8 |
9 |
10 | ngx_str_t* ngx_http_yar_read_client_post_body(ngx_http_request_t *r);
11 |
12 | yar_request* ngx_http_yar_get_yar_request(ngx_http_request_t *r,ngx_str_t *body);
13 |
14 | yar_response* ngx_http_yar_get_yar_response(ngx_http_request_t *r, yar_request *request);
15 |
16 | ngx_int_t ngx_http_yar_send_response(ngx_http_request_t *r, ngx_str_t *reply);
17 |
18 |
19 | #endif //ngx-yar-module-impl_H_
20 |
--------------------------------------------------------------------------------
/test/.gitignore:
--------------------------------------------------------------------------------
1 | CMakeCache.txt
2 | CMakeFiles
3 | Makefile
4 | cmake_install.cmake
5 | install_manifest.txt
6 | .idea
7 | *.so
8 |
--------------------------------------------------------------------------------
/test/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | project(ngx_test_yar)
2 | ADD_LIBRARY(ngx_test_yar SHARED ./yar_test_method.c)
3 | target_link_libraries(ngx_test_yar ngx_yar msgpack )
4 | install(TARGETS ngx_test_yar DESTINATION lib)
5 |
--------------------------------------------------------------------------------
/test/yar_test_method.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | /* somewhat unix-specific */
6 | #include
7 | #include
8 |
9 | /* curl stuff */
10 | #include
11 |
12 |
13 | #define HANDLECOUNT 1 /* Number of simultaneous transfers */
14 | #define HTTP_HANDLE 0 /* Index for the HTTP transfer */
15 | #define FTP_HANDLE 1 /* Index for the FTP transfer */
16 |
17 |
18 | void yar_method_test(yar_request *request, yar_response *response, void *cookie){
19 |
20 | usleep(10000);
21 |
22 | yar_packager *misko_success_pack = NULL;
23 |
24 | misko_success_pack = yar_pack_start_map(3);
25 | yar_pack_push_string(misko_success_pack,"err_code",sizeof("err_code") -1);
26 | yar_pack_push_long(misko_success_pack,0);
27 |
28 | yar_pack_push_string(misko_success_pack,"err_msg",sizeof("err_msg") -1);
29 | yar_pack_push_string(misko_success_pack,"success",sizeof("success") -1);
30 |
31 | yar_pack_push_string(misko_success_pack,"data",sizeof("data") -1);
32 | yar_pack_push_map(misko_success_pack,1);
33 |
34 | yar_pack_push_string(misko_success_pack,"count",sizeof("count") -1);
35 | yar_pack_push_long(misko_success_pack,1);
36 | yar_response_set_retval(response,misko_success_pack);
37 |
38 | yar_pack_free(misko_success_pack);
39 |
40 |
41 | }
42 |
43 |
44 | void yar_method_echo(yar_request *request,yar_response *response, void *cookie){
45 |
46 | yar_packager *packager = NULL;
47 |
48 | packager = yar_pack_start_map(3);
49 |
50 | {
51 |
52 | yar_pack_push_string(packager,"request_id",sizeof("request_id") -1);
53 | yar_pack_push_long(packager,request->id);
54 |
55 | }
56 |
57 | {
58 |
59 | yar_pack_push_string(packager,"request_method",sizeof("request_method") -1);
60 | yar_pack_push_string(packager,request->method,request->mlen);
61 |
62 | }
63 |
64 | {
65 | const yar_data *parametersData = yar_request_get_parameters(request);
66 | yar_pack_push_string(packager,"request_parameters",sizeof("request_parameters") -1);
67 | yar_pack_push_data(packager,parametersData);
68 |
69 | }
70 |
71 | yar_response_set_retval(response,packager);
72 | yar_pack_free(packager);
73 |
74 | }
75 |
76 |
77 |
78 | void yar_method_send_big_data(yar_request *request, yar_response *response, void *cookie){
79 |
80 | int size = 100000;
81 |
82 | char *log = (char *)calloc(sizeof(char) * size,1);
83 |
84 | int i=0;
85 |
86 | for(i=0;i