1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Copyright (c) 2003-2006 Niels Provos <provos@citi.umich.edu>
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * All rights reserved.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Redistribution and use in source and binary forms, with or without
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * modification, are permitted provided that the following conditions
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * are met:
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 1. Redistributions of source code must retain the above copyright
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *    notice, this list of conditions and the following disclaimer.
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 2. Redistributions in binary form must reproduce the above copyright
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *    notice, this list of conditions and the following disclaimer in the
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *    documentation and/or other materials provided with the distribution.
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 3. The name of the author may not be used to endorse or promote products
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *    derived from this software without specific prior written permission.
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef WIN32
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <winsock2.h>
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <windows.h>
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef HAVE_CONFIG_H
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "config.h"
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/types.h>
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/stat.h>
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef HAVE_SYS_TIME_H
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/time.h>
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/queue.h>
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef WIN32
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/socket.h>
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <signal.h>
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <unistd.h>
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <netdb.h>
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <fcntl.h>
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdlib.h>
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdio.h>
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string.h>
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <errno.h>
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <assert.h>
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "event.h"
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "evhttp.h"
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "log.h"
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "evrpc.h"
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "regress.gen.h"
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid rpc_suite(void);
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottextern int test_ok;
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct evhttp *
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_setup(short *pport)
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	int i;
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evhttp *myhttp;
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	short port = -1;
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* Try a few different ports */
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	for (i = 0; i < 50; ++i) {
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		myhttp = evhttp_start("127.0.0.1", 8080 + i);
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		if (myhttp != NULL) {
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			port = 8080 + i;
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			break;
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		}
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (port == -1)
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		event_errx(1, "Could not start web server");
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	*pport = port;
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return (myhttp);
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottEVRPC_HEADER(Message, msg, kill);
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottEVRPC_HEADER(NeverReply, msg, kill);
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottEVRPC_GENERATE(Message, msg, kill);
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottEVRPC_GENERATE(NeverReply, msg, kill);
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int need_input_hook = 0;
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int need_output_hook = 0;
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottMessageCb(EVRPC_STRUCT(Message)* rpc, void *arg)
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct kill* kill_reply = rpc->reply;
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (need_input_hook) {
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		struct evhttp_request* req = EVRPC_REQUEST_HTTP(rpc);
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		const char *header = evhttp_find_header(
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			req->input_headers, "X-Hook");
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		assert(strcmp(header, "input") == 0);
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* we just want to fill in some non-sense */
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVTAG_ASSIGN(kill_reply, weapon, "dagger");
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVTAG_ASSIGN(kill_reply, action, "wave around like an idiot");
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* no reply to the RPC */
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVRPC_REQUEST_DONE(rpc);
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic EVRPC_STRUCT(NeverReply) *saved_rpc;
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottNeverReplyCb(EVRPC_STRUCT(NeverReply)* rpc, void *arg)
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	test_ok += 1;
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	saved_rpc = rpc;
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottrpc_setup(struct evhttp **phttp, short *pport, struct evrpc_base **pbase)
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	short port;
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evhttp *http = NULL;
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evrpc_base *base = NULL;
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	http = http_setup(&port);
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	base = evrpc_init(http);
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVRPC_REGISTER(base, Message, msg, kill, MessageCb, NULL);
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVRPC_REGISTER(base, NeverReply, msg, kill, NeverReplyCb, NULL);
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	*phttp = http;
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	*pport = port;
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	*pbase = base;
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	need_input_hook = 0;
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	need_output_hook = 0;
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottrpc_teardown(struct evrpc_base *base)
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	assert(EVRPC_UNREGISTER(base, Message) == 0);
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	assert(EVRPC_UNREGISTER(base, NeverReply) == 0);
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evrpc_free(base);
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottrpc_postrequest_failure(struct evhttp_request *req, void *arg)
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (req->response_code != HTTP_SERVUNAVAIL) {
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stderr, "FAILED (response code)\n");
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		exit(1);
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	test_ok = 1;
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	event_loopexit(NULL);
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Test a malformed payload submitted as an RPC
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottrpc_basic_test(void)
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	short port;
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evhttp *http = NULL;
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evrpc_base *base = NULL;
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evhttp_connection *evcon = NULL;
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evhttp_request *req = NULL;
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	fprintf(stdout, "Testing Basic RPC Support: ");
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	rpc_setup(&http, &port, &base);
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evcon = evhttp_connection_new("127.0.0.1", port);
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (evcon == NULL) {
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stdout, "FAILED\n");
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		exit(1);
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/*
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	 * At this point, we want to schedule an HTTP POST request
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	 * server using our make request method.
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	 */
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	req = evhttp_request_new(rpc_postrequest_failure, NULL);
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (req == NULL) {
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stdout, "FAILED\n");
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		exit(1);
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* Add the information that we care about */
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evhttp_add_header(req->output_headers, "Host", "somehost");
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evbuffer_add_printf(req->output_buffer, "Some Nonsense");
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (evhttp_make_request(evcon, req,
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		EVHTTP_REQ_POST,
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		"/.rpc.Message") == -1) {
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stdout, "FAILED\n");
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		exit(1);
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	test_ok = 0;
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	event_dispatch();
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evhttp_connection_free(evcon);
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	rpc_teardown(base);
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (test_ok != 1) {
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stdout, "FAILED\n");
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		exit(1);
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	fprintf(stdout, "OK\n");
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evhttp_free(http);
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottrpc_postrequest_done(struct evhttp_request *req, void *arg)
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct kill* kill_reply = NULL;
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (req->response_code != HTTP_OK) {
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stderr, "FAILED (response code)\n");
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		exit(1);
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	kill_reply = kill_new();
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if ((kill_unmarshal(kill_reply, req->input_buffer)) == -1) {
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stderr, "FAILED (unmarshal)\n");
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		exit(1);
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	kill_free(kill_reply);
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	test_ok = 1;
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	event_loopexit(NULL);
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottrpc_basic_message(void)
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	short port;
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evhttp *http = NULL;
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evrpc_base *base = NULL;
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evhttp_connection *evcon = NULL;
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evhttp_request *req = NULL;
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct msg *msg;
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	fprintf(stdout, "Testing Good RPC Post: ");
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	rpc_setup(&http, &port, &base);
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evcon = evhttp_connection_new("127.0.0.1", port);
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (evcon == NULL) {
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stdout, "FAILED\n");
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		exit(1);
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/*
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	 * At this point, we want to schedule an HTTP POST request
280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	 * server using our make request method.
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	 */
282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	req = evhttp_request_new(rpc_postrequest_done, NULL);
284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (req == NULL) {
285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stdout, "FAILED\n");
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		exit(1);
287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* Add the information that we care about */
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evhttp_add_header(req->output_headers, "Host", "somehost");
291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* set up the basic message */
293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	msg = msg_new();
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVTAG_ASSIGN(msg, from_name, "niels");
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVTAG_ASSIGN(msg, to_name, "tester");
296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	msg_marshal(req->output_buffer, msg);
297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	msg_free(msg);
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (evhttp_make_request(evcon, req,
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		EVHTTP_REQ_POST,
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		"/.rpc.Message") == -1) {
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stdout, "FAILED\n");
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		exit(1);
304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	test_ok = 0;
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	event_dispatch();
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evhttp_connection_free(evcon);
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	rpc_teardown(base);
313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (test_ok != 1) {
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stdout, "FAILED\n");
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		exit(1);
317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	fprintf(stdout, "OK\n");
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evhttp_free(http);
322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct evrpc_pool *
325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottrpc_pool_with_connection(short port)
326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evhttp_connection *evcon;
328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evrpc_pool *pool;
329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	pool = evrpc_pool_new(NULL);
331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	assert(pool != NULL);
332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evcon = evhttp_connection_new("127.0.0.1", port);
334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	assert(evcon != NULL);
335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evrpc_pool_add_connection(pool, evcon);
337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return (pool);
339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottGotKillCb(struct evrpc_status *status,
343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct msg *msg, struct kill *kill, void *arg)
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	char *weapon;
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	char *action;
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (need_output_hook) {
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		struct evhttp_request *req = status->http_req;
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		const char *header = evhttp_find_header(
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			req->input_headers, "X-Pool-Hook");
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		assert(strcmp(header, "ran") == 0);
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (status->error != EVRPC_STATUS_ERR_NONE)
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		goto done;
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (EVTAG_GET(kill, weapon, &weapon) == -1) {
359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stderr, "get weapon\n");
360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		goto done;
361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (EVTAG_GET(kill, action, &action) == -1) {
363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stderr, "get action\n");
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		goto done;
365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (strcmp(weapon, "dagger"))
368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		goto done;
369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (strcmp(action, "wave around like an idiot"))
371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		goto done;
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	test_ok += 1;
374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottdone:
376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	event_loopexit(NULL);
377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottGotKillCbTwo(struct evrpc_status *status,
381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct msg *msg, struct kill *kill, void *arg)
382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	char *weapon;
384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	char *action;
385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (status->error != EVRPC_STATUS_ERR_NONE)
387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		goto done;
388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (EVTAG_GET(kill, weapon, &weapon) == -1) {
390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stderr, "get weapon\n");
391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		goto done;
392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (EVTAG_GET(kill, action, &action) == -1) {
394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stderr, "get action\n");
395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		goto done;
396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (strcmp(weapon, "dagger"))
399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		goto done;
400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (strcmp(action, "wave around like an idiot"))
402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		goto done;
403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	test_ok += 1;
405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottdone:
407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (test_ok == 2)
408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		event_loopexit(NULL);
409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int
412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottrpc_hook_add_header(struct evhttp_request *req,
413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct evbuffer *evbuf, void *arg)
414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	const char *hook_type = arg;
416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (strcmp("input", hook_type) == 0)
417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		evhttp_add_header(req->input_headers, "X-Hook", hook_type);
418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	else
419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		evhttp_add_header(req->output_headers, "X-Hook", hook_type);
420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return (0);
421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int
424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottrpc_hook_remove_header(struct evhttp_request *req,
425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct evbuffer *evbuf, void *arg)
426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	const char *header = evhttp_find_header(req->input_headers, "X-Hook");
428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	assert(header != NULL);
429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	assert(strcmp(header, arg) == 0);
430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evhttp_remove_header(req->input_headers, "X-Hook");
431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evhttp_add_header(req->input_headers, "X-Pool-Hook", "ran");
432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return (0);
434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottrpc_basic_client(void)
438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	short port;
440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evhttp *http = NULL;
441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evrpc_base *base = NULL;
442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evrpc_pool *pool = NULL;
443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct msg *msg;
444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct kill *kill;
445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	fprintf(stdout, "Testing RPC Client: ");
447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	rpc_setup(&http, &port, &base);
449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	need_input_hook = 1;
451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	need_output_hook = 1;
452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	assert(evrpc_add_hook(base, EVRPC_INPUT, rpc_hook_add_header, (void*)"input")
454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    != NULL);
455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	assert(evrpc_add_hook(base, EVRPC_OUTPUT, rpc_hook_add_header, (void*)"output")
456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    != NULL);
457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	pool = rpc_pool_with_connection(port);
459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	assert(evrpc_add_hook(pool, EVRPC_INPUT, rpc_hook_remove_header, (void*)"output"));
461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* set up the basic message */
463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	msg = msg_new();
464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVTAG_ASSIGN(msg, from_name, "niels");
465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVTAG_ASSIGN(msg, to_name, "tester");
466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	kill = kill_new();
468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVRPC_MAKE_REQUEST(Message, pool, msg, kill,  GotKillCb, NULL);
470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	test_ok = 0;
472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	event_dispatch();
474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (test_ok != 1) {
476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stdout, "FAILED (1)\n");
477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		exit(1);
478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* we do it twice to make sure that reuse works correctly */
481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	kill_clear(kill);
482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVRPC_MAKE_REQUEST(Message, pool, msg, kill,  GotKillCb, NULL);
484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	event_dispatch();
486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	rpc_teardown(base);
488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (test_ok != 2) {
490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stdout, "FAILED (2)\n");
491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		exit(1);
492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	fprintf(stdout, "OK\n");
495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	msg_free(msg);
497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	kill_free(kill);
498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evrpc_pool_free(pool);
500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evhttp_free(http);
501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * We are testing that the second requests gets send over the same
505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * connection after the first RPCs completes.
506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottrpc_basic_queued_client(void)
509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	short port;
511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evhttp *http = NULL;
512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evrpc_base *base = NULL;
513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evrpc_pool *pool = NULL;
514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct msg *msg;
515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct kill *kill_one, *kill_two;
516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	fprintf(stdout, "Testing RPC (Queued) Client: ");
518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	rpc_setup(&http, &port, &base);
520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	pool = rpc_pool_with_connection(port);
522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* set up the basic message */
524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	msg = msg_new();
525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVTAG_ASSIGN(msg, from_name, "niels");
526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVTAG_ASSIGN(msg, to_name, "tester");
527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	kill_one = kill_new();
529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	kill_two = kill_new();
530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVRPC_MAKE_REQUEST(Message, pool, msg, kill_one,  GotKillCbTwo, NULL);
532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVRPC_MAKE_REQUEST(Message, pool, msg, kill_two,  GotKillCb, NULL);
533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	test_ok = 0;
535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	event_dispatch();
537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	rpc_teardown(base);
539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (test_ok != 2) {
541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stdout, "FAILED (1)\n");
542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		exit(1);
543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	fprintf(stdout, "OK\n");
546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	msg_free(msg);
548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	kill_free(kill_one);
549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	kill_free(kill_two);
550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evrpc_pool_free(pool);
552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evhttp_free(http);
553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottGotErrorCb(struct evrpc_status *status,
557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct msg *msg, struct kill *kill, void *arg)
558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (status->error != EVRPC_STATUS_ERR_TIMEOUT)
560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		goto done;
561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* should never be complete but just to check */
563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (kill_complete(kill) == 0)
564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		goto done;
565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	test_ok += 1;
567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottdone:
569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	event_loopexit(NULL);
570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottrpc_client_timeout(void)
574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	short port;
576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evhttp *http = NULL;
577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evrpc_base *base = NULL;
578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct evrpc_pool *pool = NULL;
579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct msg *msg;
580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct kill *kill;
581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	fprintf(stdout, "Testing RPC Client Timeout: ");
583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	rpc_setup(&http, &port, &base);
585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	pool = rpc_pool_with_connection(port);
587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* set the timeout to 5 seconds */
589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evrpc_pool_set_timeout(pool, 5);
590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* set up the basic message */
592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	msg = msg_new();
593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVTAG_ASSIGN(msg, from_name, "niels");
594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVTAG_ASSIGN(msg, to_name, "tester");
595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	kill = kill_new();
597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVRPC_MAKE_REQUEST(NeverReply, pool, msg, kill, GotErrorCb, NULL);
599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	test_ok = 0;
601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	event_dispatch();
603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* free the saved RPC structure up */
605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	EVRPC_REQUEST_DONE(saved_rpc);
606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	rpc_teardown(base);
608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (test_ok != 2) {
610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stdout, "FAILED (1)\n");
611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		exit(1);
612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	fprintf(stdout, "OK\n");
615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	msg_free(msg);
617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	kill_free(kill);
618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evrpc_pool_free(pool);
620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	evhttp_free(http);
621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid
624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottrpc_suite(void)
625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	rpc_basic_test();
627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	rpc_basic_message();
628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	rpc_basic_client();
629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	rpc_basic_queued_client();
630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	rpc_client_timeout();
631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
632