Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 763 lines (576 sloc) 15.91 kb
9d9d60b @provos forgot to add file
provos authored
1 /*
2 * Copyright (c) 2003-2006 Niels Provos <provos@citi.umich.edu>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #ifdef WIN32
29 #include <winsock2.h>
30 #include <windows.h>
31 #endif
32
33 #ifdef HAVE_CONFIG_H
8889a77 Replace all use of config.h with event-config.h.
Nick Mathewson authored
34 #include "event-config.h"
9d9d60b @provos forgot to add file
provos authored
35 #endif
36
37 #include <sys/types.h>
38 #include <sys/stat.h>
8889a77 Replace all use of config.h with event-config.h.
Nick Mathewson authored
39 #ifdef _EVENT_HAVE_SYS_TIME_H
9d9d60b @provos forgot to add file
provos authored
40 #include <sys/time.h>
41 #endif
42 #include <sys/queue.h>
43 #ifndef WIN32
44 #include <sys/socket.h>
a077fb8 @provos rename sys/signal.h to signal.h; configure m4 macro dir; this assist wit...
provos authored
45 #include <signal.h>
9d9d60b @provos forgot to add file
provos authored
46 #include <unistd.h>
47 #include <netdb.h>
1e1f77c Make the test/ subdirectory buildable under Windows. Well, mingw at lea...
Nick Mathewson authored
48 #endif
9d9d60b @provos forgot to add file
provos authored
49 #include <fcntl.h>
50 #include <stdlib.h>
51 #include <stdio.h>
52 #include <string.h>
53 #include <errno.h>
ff43ed5 @provos finish RPC client support
provos authored
54 #include <assert.h>
9d9d60b @provos forgot to add file
provos authored
55
4e8a339 r19602@catbus: nickm | 2008-05-05 11:45:18 -0400
Nick Mathewson authored
56 #include "event2/event.h"
9d9d60b @provos forgot to add file
provos authored
57 #include "evhttp.h"
169321c Rename four internal headers to follow the -internal.h convention.
Nick Mathewson authored
58 #include "log-internal.h"
9d9d60b @provos forgot to add file
provos authored
59 #include "evrpc.h"
c4836d1 @provos make sure that the rpc callback receives an unmarshaled payload;
provos authored
60
9d9d60b @provos forgot to add file
provos authored
61 #include "regress.gen.h"
62
ce4ee41 r16733@catbus: nickm | 2007-11-26 14:18:25 -0500
Nick Mathewson authored
63 void rpc_suite(void);
64
c4836d1 @provos make sure that the rpc callback receives an unmarshaled payload;
provos authored
65 extern int test_ok;
66
9d9d60b @provos forgot to add file
provos authored
67 static struct evhttp *
68 http_setup(short *pport)
69 {
70 int i;
71 struct evhttp *myhttp;
72 short port = -1;
73
74 /* Try a few different ports */
75 for (i = 0; i < 50; ++i) {
76 myhttp = evhttp_start("127.0.0.1", 8080 + i);
77 if (myhttp != NULL) {
78 port = 8080 + i;
79 break;
80 }
81 }
82
83 if (port == -1)
84 event_errx(1, "Could not start web server");
85
86 *pport = port;
87 return (myhttp);
88 }
89
fda1216 @provos generate client request code via macro; flesh out the pools a little bit...
provos authored
90 EVRPC_HEADER(Message, msg, kill);
30a49b5 @provos test that rpc timeouts work correctly
provos authored
91 EVRPC_HEADER(NeverReply, msg, kill);
92
fda1216 @provos generate client request code via macro; flesh out the pools a little bit...
provos authored
93 EVRPC_GENERATE(Message, msg, kill);
30a49b5 @provos test that rpc timeouts work correctly
provos authored
94 EVRPC_GENERATE(NeverReply, msg, kill);
9d9d60b @provos forgot to add file
provos authored
95
65236aa @provos simple hooks for processing incoming and outgoing rpcs
provos authored
96 static int need_input_hook = 0;
97 static int need_output_hook = 0;
98
ce4ee41 r16733@catbus: nickm | 2007-11-26 14:18:25 -0500
Nick Mathewson authored
99 static void
30a49b5 @provos test that rpc timeouts work correctly
provos authored
100 MessageCb(EVRPC_STRUCT(Message)* rpc, void *arg)
9d9d60b @provos forgot to add file
provos authored
101 {
c4836d1 @provos make sure that the rpc callback receives an unmarshaled payload;
provos authored
102 struct kill* kill_reply = rpc->reply;
103
65236aa @provos simple hooks for processing incoming and outgoing rpcs
provos authored
104 if (need_input_hook) {
105 struct evhttp_request* req = EVRPC_REQUEST_HTTP(rpc);
106 const char *header = evhttp_find_header(
107 req->input_headers, "X-Hook");
108 assert(strcmp(header, "input") == 0);
109 }
110
c4836d1 @provos make sure that the rpc callback receives an unmarshaled payload;
provos authored
111 /* we just want to fill in some non-sense */
112 EVTAG_ASSIGN(kill_reply, weapon, "dagger");
113 EVTAG_ASSIGN(kill_reply, action, "wave around like an idiot");
114
115 /* no reply to the RPC */
116 EVRPC_REQUEST_DONE(rpc);
9d9d60b @provos forgot to add file
provos authored
117 }
118
8ee20a3 @provos fix memory leaks/unitialized memory found by valgrind
provos authored
119 static EVRPC_STRUCT(NeverReply) *saved_rpc;
120
ce4ee41 r16733@catbus: nickm | 2007-11-26 14:18:25 -0500
Nick Mathewson authored
121 static void
30a49b5 @provos test that rpc timeouts work correctly
provos authored
122 NeverReplyCb(EVRPC_STRUCT(NeverReply)* rpc, void *arg)
123 {
124 test_ok += 1;
8ee20a3 @provos fix memory leaks/unitialized memory found by valgrind
provos authored
125 saved_rpc = rpc;
30a49b5 @provos test that rpc timeouts work correctly
provos authored
126 }
127
9d9d60b @provos forgot to add file
provos authored
128 static void
c4836d1 @provos make sure that the rpc callback receives an unmarshaled payload;
provos authored
129 rpc_setup(struct evhttp **phttp, short *pport, struct evrpc_base **pbase)
9d9d60b @provos forgot to add file
provos authored
130 {
131 short port;
132 struct evhttp *http = NULL;
133 struct evrpc_base *base = NULL;
134
135 http = http_setup(&port);
136 base = evrpc_init(http);
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
137
30a49b5 @provos test that rpc timeouts work correctly
provos authored
138 EVRPC_REGISTER(base, Message, msg, kill, MessageCb, NULL);
139 EVRPC_REGISTER(base, NeverReply, msg, kill, NeverReplyCb, NULL);
c4836d1 @provos make sure that the rpc callback receives an unmarshaled payload;
provos authored
140
141 *phttp = http;
142 *pport = port;
143 *pbase = base;
65236aa @provos simple hooks for processing incoming and outgoing rpcs
provos authored
144
145 need_input_hook = 0;
146 need_output_hook = 0;
c4836d1 @provos make sure that the rpc callback receives an unmarshaled payload;
provos authored
147 }
148
149 static void
0c28082 @provos support removing of http callbacks and removing of registered RPCs
provos authored
150 rpc_teardown(struct evrpc_base *base)
151 {
152 assert(EVRPC_UNREGISTER(base, Message) == 0);
153 assert(EVRPC_UNREGISTER(base, NeverReply) == 0);
621a1b2 @provos support freeing of evrpc base
provos authored
154
155 evrpc_free(base);
0c28082 @provos support removing of http callbacks and removing of registered RPCs
provos authored
156 }
157
158 static void
c4836d1 @provos make sure that the rpc callback receives an unmarshaled payload;
provos authored
159 rpc_postrequest_failure(struct evhttp_request *req, void *arg)
160 {
161 if (req->response_code != HTTP_SERVUNAVAIL) {
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
162
c4836d1 @provos make sure that the rpc callback receives an unmarshaled payload;
provos authored
163 fprintf(stderr, "FAILED (response code)\n");
164 exit(1);
165 }
166
167 test_ok = 1;
168 event_loopexit(NULL);
169 }
170
171 /*
172 * Test a malformed payload submitted as an RPC
173 */
174
175 static void
176 rpc_basic_test(void)
177 {
178 short port;
179 struct evhttp *http = NULL;
180 struct evrpc_base *base = NULL;
181 struct evhttp_connection *evcon = NULL;
182 struct evhttp_request *req = NULL;
183
184 fprintf(stdout, "Testing Basic RPC Support: ");
185
186 rpc_setup(&http, &port, &base);
187
188 evcon = evhttp_connection_new("127.0.0.1", port);
189 if (evcon == NULL) {
190 fprintf(stdout, "FAILED\n");
191 exit(1);
192 }
193
194 /*
195 * At this point, we want to schedule an HTTP POST request
196 * server using our make request method.
197 */
198
199 req = evhttp_request_new(rpc_postrequest_failure, NULL);
200 if (req == NULL) {
201 fprintf(stdout, "FAILED\n");
202 exit(1);
203 }
204
205 /* Add the information that we care about */
206 evhttp_add_header(req->output_headers, "Host", "somehost");
207 evbuffer_add_printf(req->output_buffer, "Some Nonsense");
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
208
c4836d1 @provos make sure that the rpc callback receives an unmarshaled payload;
provos authored
209 if (evhttp_make_request(evcon, req,
210 EVHTTP_REQ_POST,
211 "/.rpc.Message") == -1) {
212 fprintf(stdout, "FAILED\n");
213 exit(1);
214 }
215
216 test_ok = 0;
217
218 event_dispatch();
0c28082 @provos support removing of http callbacks and removing of registered RPCs
provos authored
219
e678f00 @provos fix a couple memory leaks; time buffer marshaling
provos authored
220 evhttp_connection_free(evcon);
221
0c28082 @provos support removing of http callbacks and removing of registered RPCs
provos authored
222 rpc_teardown(base);
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
223
c4836d1 @provos make sure that the rpc callback receives an unmarshaled payload;
provos authored
224 if (test_ok != 1) {
225 fprintf(stdout, "FAILED\n");
226 exit(1);
227 }
228
229 fprintf(stdout, "OK\n");
230
231 evhttp_free(http);
232 }
233
234 static void
235 rpc_postrequest_done(struct evhttp_request *req, void *arg)
236 {
237 struct kill* kill_reply = NULL;
238
239 if (req->response_code != HTTP_OK) {
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
240
c4836d1 @provos make sure that the rpc callback receives an unmarshaled payload;
provos authored
241 fprintf(stderr, "FAILED (response code)\n");
242 exit(1);
243 }
244
245 kill_reply = kill_new();
246
247 if ((kill_unmarshal(kill_reply, req->input_buffer)) == -1) {
248 fprintf(stderr, "FAILED (unmarshal)\n");
249 exit(1);
250 }
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
251
c4836d1 @provos make sure that the rpc callback receives an unmarshaled payload;
provos authored
252 kill_free(kill_reply);
253
254 test_ok = 1;
255 event_loopexit(NULL);
256 }
257
258 static void
259 rpc_basic_message(void)
260 {
261 short port;
262 struct evhttp *http = NULL;
263 struct evrpc_base *base = NULL;
264 struct evhttp_connection *evcon = NULL;
265 struct evhttp_request *req = NULL;
266 struct msg *msg;
267
268 fprintf(stdout, "Testing Good RPC Post: ");
269
270 rpc_setup(&http, &port, &base);
271
272 evcon = evhttp_connection_new("127.0.0.1", port);
273 if (evcon == NULL) {
274 fprintf(stdout, "FAILED\n");
275 exit(1);
276 }
277
278 /*
279 * At this point, we want to schedule an HTTP POST request
280 * server using our make request method.
281 */
282
283 req = evhttp_request_new(rpc_postrequest_done, NULL);
284 if (req == NULL) {
285 fprintf(stdout, "FAILED\n");
286 exit(1);
287 }
288
289 /* Add the information that we care about */
290 evhttp_add_header(req->output_headers, "Host", "somehost");
291
292 /* set up the basic message */
293 msg = msg_new();
294 EVTAG_ASSIGN(msg, from_name, "niels");
295 EVTAG_ASSIGN(msg, to_name, "tester");
296 msg_marshal(req->output_buffer, msg);
297 msg_free(msg);
298
299 if (evhttp_make_request(evcon, req,
300 EVHTTP_REQ_POST,
301 "/.rpc.Message") == -1) {
302 fprintf(stdout, "FAILED\n");
303 exit(1);
304 }
305
306 test_ok = 0;
307
9d9d60b @provos forgot to add file
provos authored
308 event_dispatch();
e678f00 @provos fix a couple memory leaks; time buffer marshaling
provos authored
309
310 evhttp_connection_free(evcon);
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
311
0c28082 @provos support removing of http callbacks and removing of registered RPCs
provos authored
312 rpc_teardown(base);
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
313
c4836d1 @provos make sure that the rpc callback receives an unmarshaled payload;
provos authored
314 if (test_ok != 1) {
315 fprintf(stdout, "FAILED\n");
316 exit(1);
317 }
318
9d9d60b @provos forgot to add file
provos authored
319 fprintf(stdout, "OK\n");
c4836d1 @provos make sure that the rpc callback receives an unmarshaled payload;
provos authored
320
321 evhttp_free(http);
9d9d60b @provos forgot to add file
provos authored
322 }
323
ff43ed5 @provos finish RPC client support
provos authored
324 static struct evrpc_pool *
325 rpc_pool_with_connection(short port)
326 {
327 struct evhttp_connection *evcon;
328 struct evrpc_pool *pool;
329
1d3a008 @provos provide hooks for outgoing pools; associate a base with a pool
provos authored
330 pool = evrpc_pool_new(NULL);
ff43ed5 @provos finish RPC client support
provos authored
331 assert(pool != NULL);
332
333 evcon = evhttp_connection_new("127.0.0.1", port);
334 assert(evcon != NULL);
335
336 evrpc_pool_add_connection(pool, evcon);
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
337
ff43ed5 @provos finish RPC client support
provos authored
338 return (pool);
339 }
340
341 static void
3794534 @provos change the signature of the client rpc callback to pass in an rpc status...
provos authored
342 GotKillCb(struct evrpc_status *status,
343 struct msg *msg, struct kill *kill, void *arg)
ff43ed5 @provos finish RPC client support
provos authored
344 {
345 char *weapon;
346 char *action;
347
65236aa @provos simple hooks for processing incoming and outgoing rpcs
provos authored
348 if (need_output_hook) {
349 struct evhttp_request *req = status->http_req;
350 const char *header = evhttp_find_header(
1d3a008 @provos provide hooks for outgoing pools; associate a base with a pool
provos authored
351 req->input_headers, "X-Pool-Hook");
352 assert(strcmp(header, "ran") == 0);
65236aa @provos simple hooks for processing incoming and outgoing rpcs
provos authored
353 }
354
3794534 @provos change the signature of the client rpc callback to pass in an rpc status...
provos authored
355 if (status->error != EVRPC_STATUS_ERR_NONE)
356 goto done;
357
ff43ed5 @provos finish RPC client support
provos authored
358 if (EVTAG_GET(kill, weapon, &weapon) == -1) {
359 fprintf(stderr, "get weapon\n");
360 goto done;
361 }
362 if (EVTAG_GET(kill, action, &action) == -1) {
363 fprintf(stderr, "get action\n");
364 goto done;
365 }
366
367 if (strcmp(weapon, "dagger"))
368 goto done;
369
370 if (strcmp(action, "wave around like an idiot"))
371 goto done;
372
373 test_ok += 1;
2d028ef @provos fix a bug where rpc would not be scheduled when they were queued; test f...
provos authored
374
ff43ed5 @provos finish RPC client support
provos authored
375 done:
376 event_loopexit(NULL);
377 }
378
379 static void
3794534 @provos change the signature of the client rpc callback to pass in an rpc status...
provos authored
380 GotKillCbTwo(struct evrpc_status *status,
381 struct msg *msg, struct kill *kill, void *arg)
2d028ef @provos fix a bug where rpc would not be scheduled when they were queued; test f...
provos authored
382 {
383 char *weapon;
384 char *action;
385
3794534 @provos change the signature of the client rpc callback to pass in an rpc status...
provos authored
386 if (status->error != EVRPC_STATUS_ERR_NONE)
387 goto done;
388
2d028ef @provos fix a bug where rpc would not be scheduled when they were queued; test f...
provos authored
389 if (EVTAG_GET(kill, weapon, &weapon) == -1) {
390 fprintf(stderr, "get weapon\n");
391 goto done;
392 }
393 if (EVTAG_GET(kill, action, &action) == -1) {
394 fprintf(stderr, "get action\n");
395 goto done;
396 }
397
398 if (strcmp(weapon, "dagger"))
399 goto done;
400
401 if (strcmp(action, "wave around like an idiot"))
402 goto done;
403
404 test_ok += 1;
405
406 done:
407 if (test_ok == 2)
408 event_loopexit(NULL);
409 }
410
65236aa @provos simple hooks for processing incoming and outgoing rpcs
provos authored
411 static int
819d4a3 @provos allow hooks to pause RPC processing; this will allow hooks to do meaning...
provos authored
412 rpc_hook_add_header(void *ctx, struct evhttp_request *req,
65236aa @provos simple hooks for processing incoming and outgoing rpcs
provos authored
413 struct evbuffer *evbuf, void *arg)
414 {
415 const char *hook_type = arg;
416 if (strcmp("input", hook_type) == 0)
417 evhttp_add_header(req->input_headers, "X-Hook", hook_type);
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
418 else
65236aa @provos simple hooks for processing incoming and outgoing rpcs
provos authored
419 evhttp_add_header(req->output_headers, "X-Hook", hook_type);
5a5609c @provos allow association of meta data with RPC requests for hook processing
provos authored
420
2460aa5 @provos allow hooks to get access to the connection object
provos authored
421 assert(evrpc_hook_get_connection(ctx) != NULL);
422
5a5609c @provos allow association of meta data with RPC requests for hook processing
provos authored
423 return (EVRPC_CONTINUE);
424 }
425
426 static int
427 rpc_hook_add_meta(void *ctx, struct evhttp_request *req,
428 struct evbuffer *evbuf, void *arg)
429 {
430 evrpc_hook_add_meta(ctx, "meta", "test", 5);
431
2460aa5 @provos allow hooks to get access to the connection object
provos authored
432 assert(evrpc_hook_get_connection(ctx) != NULL);
433
5a5609c @provos allow association of meta data with RPC requests for hook processing
provos authored
434 return (EVRPC_CONTINUE);
65236aa @provos simple hooks for processing incoming and outgoing rpcs
provos authored
435 }
436
1d3a008 @provos provide hooks for outgoing pools; associate a base with a pool
provos authored
437 static int
819d4a3 @provos allow hooks to pause RPC processing; this will allow hooks to do meaning...
provos authored
438 rpc_hook_remove_header(void *ctx, struct evhttp_request *req,
1d3a008 @provos provide hooks for outgoing pools; associate a base with a pool
provos authored
439 struct evbuffer *evbuf, void *arg)
440 {
441 const char *header = evhttp_find_header(req->input_headers, "X-Hook");
5a5609c @provos allow association of meta data with RPC requests for hook processing
provos authored
442 void *data = NULL;
443 size_t data_len = 0;
444
1d3a008 @provos provide hooks for outgoing pools; associate a base with a pool
provos authored
445 assert(header != NULL);
446 assert(strcmp(header, arg) == 0);
5a5609c @provos allow association of meta data with RPC requests for hook processing
provos authored
447
1d3a008 @provos provide hooks for outgoing pools; associate a base with a pool
provos authored
448 evhttp_remove_header(req->input_headers, "X-Hook");
449 evhttp_add_header(req->input_headers, "X-Pool-Hook", "ran");
450
5a5609c @provos allow association of meta data with RPC requests for hook processing
provos authored
451 assert(evrpc_hook_find_meta(ctx, "meta", &data, &data_len) == 0);
452 assert(data != NULL);
453 assert(data_len == 5);
454
2460aa5 @provos allow hooks to get access to the connection object
provos authored
455 assert(evrpc_hook_get_connection(ctx) != NULL);
456
5a5609c @provos allow association of meta data with RPC requests for hook processing
provos authored
457 return (EVRPC_CONTINUE);
1d3a008 @provos provide hooks for outgoing pools; associate a base with a pool
provos authored
458 }
459
2d028ef @provos fix a bug where rpc would not be scheduled when they were queued; test f...
provos authored
460 static void
ff43ed5 @provos finish RPC client support
provos authored
461 rpc_basic_client(void)
462 {
463 short port;
464 struct evhttp *http = NULL;
465 struct evrpc_base *base = NULL;
466 struct evrpc_pool *pool = NULL;
467 struct msg *msg;
468 struct kill *kill;
469
470 fprintf(stdout, "Testing RPC Client: ");
471
472 rpc_setup(&http, &port, &base);
473
65236aa @provos simple hooks for processing incoming and outgoing rpcs
provos authored
474 need_input_hook = 1;
475 need_output_hook = 1;
476
2baaac7 Forward-port: Rename INPUT and OUTPUT to EVRPC_INPUT and EVRPC_OUTPUT, ...
Nick Mathewson authored
477 assert(evrpc_add_hook(base, EVRPC_INPUT, rpc_hook_add_header, (void*)"input")
65236aa @provos simple hooks for processing incoming and outgoing rpcs
provos authored
478 != NULL);
2baaac7 Forward-port: Rename INPUT and OUTPUT to EVRPC_INPUT and EVRPC_OUTPUT, ...
Nick Mathewson authored
479 assert(evrpc_add_hook(base, EVRPC_OUTPUT, rpc_hook_add_header, (void*)"output")
65236aa @provos simple hooks for processing incoming and outgoing rpcs
provos authored
480 != NULL);
481
ff43ed5 @provos finish RPC client support
provos authored
482 pool = rpc_pool_with_connection(port);
483
2baaac7 Forward-port: Rename INPUT and OUTPUT to EVRPC_INPUT and EVRPC_OUTPUT, ...
Nick Mathewson authored
484 assert(evrpc_add_hook(pool, EVRPC_OUTPUT, rpc_hook_add_meta, NULL));
485 assert(evrpc_add_hook(pool, EVRPC_INPUT, rpc_hook_remove_header, (void*)"output"));
1d3a008 @provos provide hooks for outgoing pools; associate a base with a pool
provos authored
486
ff43ed5 @provos finish RPC client support
provos authored
487 /* set up the basic message */
488 msg = msg_new();
489 EVTAG_ASSIGN(msg, from_name, "niels");
490 EVTAG_ASSIGN(msg, to_name, "tester");
491
492 kill = kill_new();
493
50edb19 @provos EVRPC_MAKE_REQUEST needs the pool argument
provos authored
494 EVRPC_MAKE_REQUEST(Message, pool, msg, kill, GotKillCb, NULL);
ff43ed5 @provos finish RPC client support
provos authored
495
496 test_ok = 0;
497
498 event_dispatch();
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
499
ff43ed5 @provos finish RPC client support
provos authored
500 if (test_ok != 1) {
501 fprintf(stdout, "FAILED (1)\n");
502 exit(1);
503 }
504
505 /* we do it twice to make sure that reuse works correctly */
506 kill_clear(kill);
507
50edb19 @provos EVRPC_MAKE_REQUEST needs the pool argument
provos authored
508 EVRPC_MAKE_REQUEST(Message, pool, msg, kill, GotKillCb, NULL);
ff43ed5 @provos finish RPC client support
provos authored
509
510 event_dispatch();
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
511
ff43ed5 @provos finish RPC client support
provos authored
512 if (test_ok != 2) {
513 fprintf(stdout, "FAILED (2)\n");
514 exit(1);
515 }
516
e8f450f @provos expose a way to create the rpc context manually
provos authored
517
518 /* we do it trice to make sure other stuff works, too */
519 kill_clear(kill);
520
521 {
522 struct evrpc_request_wrapper *ctx =
523 EVRPC_MAKE_CTX(Message, msg, kill,
524 pool, msg, kill, GotKillCb, NULL);
525 evrpc_make_request(ctx);
526 }
527
528 event_dispatch();
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
529
e8f450f @provos expose a way to create the rpc context manually
provos authored
530 rpc_teardown(base);
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
531
e8f450f @provos expose a way to create the rpc context manually
provos authored
532 if (test_ok != 3) {
533 fprintf(stdout, "FAILED (3)\n");
534 exit(1);
535 }
536
ff43ed5 @provos finish RPC client support
provos authored
537 fprintf(stdout, "OK\n");
538
539 msg_free(msg);
540 kill_free(kill);
541
542 evrpc_pool_free(pool);
543 evhttp_free(http);
819d4a3 @provos allow hooks to pause RPC processing; this will allow hooks to do meaning...
provos authored
544
545 need_input_hook = 0;
546 need_output_hook = 0;
ff43ed5 @provos finish RPC client support
provos authored
547 }
548
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
549 /*
2d028ef @provos fix a bug where rpc would not be scheduled when they were queued; test f...
provos authored
550 * We are testing that the second requests gets send over the same
551 * connection after the first RPCs completes.
552 */
553 static void
554 rpc_basic_queued_client(void)
555 {
556 short port;
557 struct evhttp *http = NULL;
558 struct evrpc_base *base = NULL;
559 struct evrpc_pool *pool = NULL;
560 struct msg *msg;
561 struct kill *kill_one, *kill_two;
562
563 fprintf(stdout, "Testing RPC (Queued) Client: ");
564
565 rpc_setup(&http, &port, &base);
566
567 pool = rpc_pool_with_connection(port);
568
569 /* set up the basic message */
570 msg = msg_new();
571 EVTAG_ASSIGN(msg, from_name, "niels");
572 EVTAG_ASSIGN(msg, to_name, "tester");
573
574 kill_one = kill_new();
575 kill_two = kill_new();
576
50edb19 @provos EVRPC_MAKE_REQUEST needs the pool argument
provos authored
577 EVRPC_MAKE_REQUEST(Message, pool, msg, kill_one, GotKillCbTwo, NULL);
578 EVRPC_MAKE_REQUEST(Message, pool, msg, kill_two, GotKillCb, NULL);
2d028ef @provos fix a bug where rpc would not be scheduled when they were queued; test f...
provos authored
579
580 test_ok = 0;
581
582 event_dispatch();
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
583
0c28082 @provos support removing of http callbacks and removing of registered RPCs
provos authored
584 rpc_teardown(base);
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
585
2d028ef @provos fix a bug where rpc would not be scheduled when they were queued; test f...
provos authored
586 if (test_ok != 2) {
587 fprintf(stdout, "FAILED (1)\n");
588 exit(1);
589 }
590
591 fprintf(stdout, "OK\n");
592
593 msg_free(msg);
594 kill_free(kill_one);
595 kill_free(kill_two);
596
597 evrpc_pool_free(pool);
598 evhttp_free(http);
599 }
600
30a49b5 @provos test that rpc timeouts work correctly
provos authored
601 static void
3794534 @provos change the signature of the client rpc callback to pass in an rpc status...
provos authored
602 GotErrorCb(struct evrpc_status *status,
603 struct msg *msg, struct kill *kill, void *arg)
30a49b5 @provos test that rpc timeouts work correctly
provos authored
604 {
3794534 @provos change the signature of the client rpc callback to pass in an rpc status...
provos authored
605 if (status->error != EVRPC_STATUS_ERR_TIMEOUT)
606 goto done;
607
30a49b5 @provos test that rpc timeouts work correctly
provos authored
608 /* should never be complete but just to check */
609 if (kill_complete(kill) == 0)
610 goto done;
611
612 test_ok += 1;
613
614 done:
615 event_loopexit(NULL);
616 }
617
819d4a3 @provos allow hooks to pause RPC processing; this will allow hooks to do meaning...
provos authored
618 /* we just pause the rpc and continue it in the next callback */
619
620 struct _rpc_hook_ctx {
621 void *vbase;
622 void *ctx;
623 };
624
955c6ab @provos pausing an rpc via a hook needs to deal with the fact that http callback...
provos authored
625 static int hook_pause_cb_called;
626
819d4a3 @provos allow hooks to pause RPC processing; this will allow hooks to do meaning...
provos authored
627 static void
628 rpc_hook_pause_cb(int fd, short what, void *arg)
629 {
630 struct _rpc_hook_ctx *ctx = arg;
955c6ab @provos pausing an rpc via a hook needs to deal with the fact that http callback...
provos authored
631 ++hook_pause_cb_called;
819d4a3 @provos allow hooks to pause RPC processing; this will allow hooks to do meaning...
provos authored
632 evrpc_resume_request(ctx->vbase, ctx->ctx, EVRPC_CONTINUE);
633 }
634
635 static int
636 rpc_hook_pause(void *ctx, struct evhttp_request *req, struct evbuffer *evbuf,
637 void *arg)
638 {
639 struct _rpc_hook_ctx *tmp = malloc(sizeof(*tmp));
640 struct timeval tv;
641
642 assert(tmp != NULL);
643 tmp->vbase = arg;
644 tmp->ctx = ctx;
645
646 memset(&tv, 0, sizeof(tv));
647 event_once(-1, EV_TIMEOUT, rpc_hook_pause_cb, tmp, &tv);
648 return EVRPC_PAUSE;
649 }
650
651 static void
652 rpc_basic_client_with_pause(void)
653 {
654 short port;
655 struct evhttp *http = NULL;
656 struct evrpc_base *base = NULL;
657 struct evrpc_pool *pool = NULL;
658 struct msg *msg;
659 struct kill *kill;
660
661 fprintf(stdout, "Testing RPC Client with pause hooks: ");
662
663 rpc_setup(&http, &port, &base);
664
2baaac7 Forward-port: Rename INPUT and OUTPUT to EVRPC_INPUT and EVRPC_OUTPUT, ...
Nick Mathewson authored
665 assert(evrpc_add_hook(base, EVRPC_INPUT, rpc_hook_pause, base));
666 assert(evrpc_add_hook(base, EVRPC_OUTPUT, rpc_hook_pause, base));
819d4a3 @provos allow hooks to pause RPC processing; this will allow hooks to do meaning...
provos authored
667
668 pool = rpc_pool_with_connection(port);
669
2baaac7 Forward-port: Rename INPUT and OUTPUT to EVRPC_INPUT and EVRPC_OUTPUT, ...
Nick Mathewson authored
670 assert(evrpc_add_hook(pool, EVRPC_INPUT, rpc_hook_pause, pool));
671 assert(evrpc_add_hook(pool, EVRPC_OUTPUT, rpc_hook_pause, pool));
819d4a3 @provos allow hooks to pause RPC processing; this will allow hooks to do meaning...
provos authored
672
673 /* set up the basic message */
674 msg = msg_new();
675 EVTAG_ASSIGN(msg, from_name, "niels");
676 EVTAG_ASSIGN(msg, to_name, "tester");
677
678 kill = kill_new();
679
955c6ab @provos pausing an rpc via a hook needs to deal with the fact that http callback...
provos authored
680 EVRPC_MAKE_REQUEST(Message, pool, msg, kill, GotKillCb, NULL);
819d4a3 @provos allow hooks to pause RPC processing; this will allow hooks to do meaning...
provos authored
681
682 test_ok = 0;
683
684 event_dispatch();
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
685
955c6ab @provos pausing an rpc via a hook needs to deal with the fact that http callback...
provos authored
686 if (test_ok != 1 || hook_pause_cb_called != 4) {
687 fprintf(stdout, "FAILED\n");
819d4a3 @provos allow hooks to pause RPC processing; this will allow hooks to do meaning...
provos authored
688 exit(1);
689 }
690
691 rpc_teardown(base);
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
692
819d4a3 @provos allow hooks to pause RPC processing; this will allow hooks to do meaning...
provos authored
693 fprintf(stdout, "OK\n");
694
695 msg_free(msg);
696 kill_free(kill);
697
698 evrpc_pool_free(pool);
699 evhttp_free(http);
700 }
701
30a49b5 @provos test that rpc timeouts work correctly
provos authored
702 static void
703 rpc_client_timeout(void)
704 {
705 short port;
706 struct evhttp *http = NULL;
707 struct evrpc_base *base = NULL;
708 struct evrpc_pool *pool = NULL;
709 struct msg *msg;
710 struct kill *kill;
711
712 fprintf(stdout, "Testing RPC Client Timeout: ");
713
714 rpc_setup(&http, &port, &base);
715
716 pool = rpc_pool_with_connection(port);
717
718 /* set the timeout to 5 seconds */
719 evrpc_pool_set_timeout(pool, 5);
720
721 /* set up the basic message */
722 msg = msg_new();
723 EVTAG_ASSIGN(msg, from_name, "niels");
724 EVTAG_ASSIGN(msg, to_name, "tester");
725
726 kill = kill_new();
727
3794534 @provos change the signature of the client rpc callback to pass in an rpc status...
provos authored
728 EVRPC_MAKE_REQUEST(NeverReply, pool, msg, kill, GotErrorCb, NULL);
30a49b5 @provos test that rpc timeouts work correctly
provos authored
729
730 test_ok = 0;
731
732 event_dispatch();
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
733
8ee20a3 @provos fix memory leaks/unitialized memory found by valgrind
provos authored
734 /* free the saved RPC structure up */
735 EVRPC_REQUEST_DONE(saved_rpc);
736
0c28082 @provos support removing of http callbacks and removing of registered RPCs
provos authored
737 rpc_teardown(base);
9993137 Remove all trailing whitespace in all the source files.
Nick Mathewson authored
738
30a49b5 @provos test that rpc timeouts work correctly
provos authored
739 if (test_ok != 2) {
740 fprintf(stdout, "FAILED (1)\n");
741 exit(1);
742 }
743
744 fprintf(stdout, "OK\n");
745
746 msg_free(msg);
747 kill_free(kill);
748
749 evrpc_pool_free(pool);
750 evhttp_free(http);
751 }
2d028ef @provos fix a bug where rpc would not be scheduled when they were queued; test f...
provos authored
752
9d9d60b @provos forgot to add file
provos authored
753 void
754 rpc_suite(void)
755 {
756 rpc_basic_test();
c4836d1 @provos make sure that the rpc callback receives an unmarshaled payload;
provos authored
757 rpc_basic_message();
ff43ed5 @provos finish RPC client support
provos authored
758 rpc_basic_client();
2d028ef @provos fix a bug where rpc would not be scheduled when they were queued; test f...
provos authored
759 rpc_basic_queued_client();
819d4a3 @provos allow hooks to pause RPC processing; this will allow hooks to do meaning...
provos authored
760 rpc_basic_client_with_pause();
30a49b5 @provos test that rpc timeouts work correctly
provos authored
761 rpc_client_timeout();
9d9d60b @provos forgot to add file
provos authored
762 }
Something went wrong with that request. Please try again.