xref: /netbsd-src/external/bsd/ntp/dist/sntp/libevent/test/bench_http.c (revision eabc0478de71e4e011a5b4e0392741e01d491794)
1*eabc0478Schristos /*	$NetBSD: bench_http.c,v 1.6 2024/08/18 20:47:23 christos Exp $	*/
28585484eSchristos 
38585484eSchristos /*
48585484eSchristos  * Copyright 2008-2012 Niels Provos and Nick Mathewson
58585484eSchristos  *
68585484eSchristos  * Redistribution and use in source and binary forms, with or without
78585484eSchristos  * modification, are permitted provided that the following conditions
88585484eSchristos  * are met:
98585484eSchristos  * 1. Redistributions of source code must retain the above copyright
108585484eSchristos  *    notice, this list of conditions and the following disclaimer.
118585484eSchristos  * 2. Redistributions in binary form must reproduce the above copyright
128585484eSchristos  *    notice, this list of conditions and the following disclaimer in the
138585484eSchristos  *    documentation and/or other materials provided with the distribution.
148585484eSchristos  * 4. The name of the author may not be used to endorse or promote products
158585484eSchristos  *    derived from this software without specific prior written permission.
168585484eSchristos  *
178585484eSchristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
188585484eSchristos  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
198585484eSchristos  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
208585484eSchristos  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
218585484eSchristos  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
228585484eSchristos  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
238585484eSchristos  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
248585484eSchristos  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258585484eSchristos  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
268585484eSchristos  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278585484eSchristos  *
288585484eSchristos  */
298585484eSchristos 
308585484eSchristos #include <sys/types.h>
318585484eSchristos #include <sys/stat.h>
328585484eSchristos #ifdef _WIN32
338585484eSchristos #include <winsock2.h>
348585484eSchristos #else
358585484eSchristos #include <sys/socket.h>
368585484eSchristos #include <sys/resource.h>
378585484eSchristos #include <sys/time.h>
388585484eSchristos #include <unistd.h>
398585484eSchristos #endif
408585484eSchristos #include <fcntl.h>
418585484eSchristos #include <signal.h>
428585484eSchristos #include <stdlib.h>
438585484eSchristos #include <stdio.h>
448585484eSchristos #include <string.h>
458585484eSchristos #include <errno.h>
468585484eSchristos 
478585484eSchristos #include "event2/event.h"
488585484eSchristos #include "event2/buffer.h"
498585484eSchristos #include "event2/util.h"
508585484eSchristos #include "event2/http.h"
518585484eSchristos #include "event2/thread.h"
528585484eSchristos 
538585484eSchristos static void http_basic_cb(struct evhttp_request *req, void *arg);
548585484eSchristos 
558585484eSchristos static char *content;
568585484eSchristos static size_t content_len = 0;
578585484eSchristos 
588585484eSchristos static void
598585484eSchristos http_basic_cb(struct evhttp_request *req, void *arg)
608585484eSchristos {
618585484eSchristos 	struct evbuffer *evb = evbuffer_new();
628585484eSchristos 
638585484eSchristos 	evbuffer_add(evb, content, content_len);
648585484eSchristos 
658585484eSchristos 	/* allow sending of an empty reply */
668585484eSchristos 	evhttp_send_reply(req, HTTP_OK, "Everything is fine", evb);
678585484eSchristos 
688585484eSchristos 	evbuffer_free(evb);
698585484eSchristos }
708585484eSchristos 
718585484eSchristos #if LIBEVENT_VERSION_NUMBER >= 0x02000200
728585484eSchristos static void
738585484eSchristos http_ref_cb(struct evhttp_request *req, void *arg)
748585484eSchristos {
758585484eSchristos 	struct evbuffer *evb = evbuffer_new();
768585484eSchristos 
778585484eSchristos 	evbuffer_add_reference(evb, content, content_len, NULL, NULL);
788585484eSchristos 
798585484eSchristos 	/* allow sending of an empty reply */
808585484eSchristos 	evhttp_send_reply(req, HTTP_OK, "Everything is fine", evb);
818585484eSchristos 
828585484eSchristos 	evbuffer_free(evb);
838585484eSchristos }
848585484eSchristos #endif
858585484eSchristos 
868585484eSchristos int
878585484eSchristos main(int argc, char **argv)
888585484eSchristos {
898585484eSchristos 	struct event_config *cfg = event_config_new();
908585484eSchristos 	struct event_base *base;
918585484eSchristos 	struct evhttp *http;
928585484eSchristos 	int i;
938585484eSchristos 	int c;
948585484eSchristos 	int use_iocp = 0;
95*eabc0478Schristos 	ev_uint16_t port = 8080;
968585484eSchristos 	char *endptr = NULL;
978585484eSchristos 
988585484eSchristos #ifdef _WIN32
998585484eSchristos 	WSADATA WSAData;
1008585484eSchristos 	WSAStartup(0x101, &WSAData);
1018585484eSchristos #else
1028585484eSchristos 	if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
1038585484eSchristos 		return (1);
1048585484eSchristos #endif
1058585484eSchristos 
106*eabc0478Schristos 	setbuf(stdout, NULL);
107*eabc0478Schristos 	setbuf(stderr, NULL);
108*eabc0478Schristos 
1098585484eSchristos 	for (i = 1; i < argc; ++i) {
1108585484eSchristos 		if (*argv[i] != '-')
1118585484eSchristos 			continue;
1128585484eSchristos 
1138585484eSchristos 		c = argv[i][1];
1148585484eSchristos 
1158585484eSchristos 		if ((c == 'p' || c == 'l') && i + 1 >= argc) {
1168585484eSchristos 			fprintf(stderr, "-%c requires argument.\n", c);
1178585484eSchristos 			exit(1);
1188585484eSchristos 		}
1198585484eSchristos 
1208585484eSchristos 		switch (c) {
1218585484eSchristos 		case 'p':
1228585484eSchristos 			if (i+1 >= argc || !argv[i+1]) {
1238585484eSchristos 				fprintf(stderr, "Missing port\n");
1248585484eSchristos 				exit(1);
1258585484eSchristos 			}
1268585484eSchristos 			port = (int)strtol(argv[i+1], &endptr, 10);
1278585484eSchristos 			if (*endptr != '\0') {
1288585484eSchristos 				fprintf(stderr, "Bad port\n");
1298585484eSchristos 				exit(1);
1308585484eSchristos 			}
1318585484eSchristos 			break;
1328585484eSchristos 		case 'l':
1338585484eSchristos 			if (i+1 >= argc || !argv[i+1]) {
1348585484eSchristos 				fprintf(stderr, "Missing content length\n");
1358585484eSchristos 				exit(1);
1368585484eSchristos 			}
1378585484eSchristos 			content_len = (size_t)strtol(argv[i+1], &endptr, 10);
1388585484eSchristos 			if (*endptr != '\0' || content_len == 0) {
1398585484eSchristos 				fprintf(stderr, "Bad content length\n");
1408585484eSchristos 				exit(1);
1418585484eSchristos 			}
1428585484eSchristos 			break;
1438585484eSchristos #ifdef _WIN32
1448585484eSchristos 		case 'i':
1458585484eSchristos 			use_iocp = 1;
146*eabc0478Schristos #ifdef EVTHREAD_USE_WINDOWS_THREADS_IMPLEMENTED
1478585484eSchristos 			evthread_use_windows_threads();
148*eabc0478Schristos #endif
1498585484eSchristos 			event_config_set_flag(cfg,EVENT_BASE_FLAG_STARTUP_IOCP);
1508585484eSchristos 			break;
1518585484eSchristos #endif
1528585484eSchristos 		default:
1538585484eSchristos 			fprintf(stderr, "Illegal argument \"%c\"\n", c);
1548585484eSchristos 			exit(1);
1558585484eSchristos 		}
1568585484eSchristos 	}
1578585484eSchristos 
1588585484eSchristos 	base = event_base_new_with_config(cfg);
1598585484eSchristos 	if (!base) {
1608585484eSchristos 		fprintf(stderr, "creating event_base failed. Exiting.\n");
1618585484eSchristos 		return 1;
1628585484eSchristos 	}
1638585484eSchristos 
1648585484eSchristos 	http = evhttp_new(base);
1658585484eSchristos 
1668585484eSchristos 	content = malloc(content_len);
1678585484eSchristos 	if (content == NULL) {
1688585484eSchristos 		fprintf(stderr, "Cannot allocate content\n");
1698585484eSchristos 		exit(1);
1708585484eSchristos 	} else {
1718585484eSchristos 		int i = 0;
1728585484eSchristos 		for (i = 0; i < (int)content_len; ++i)
1738585484eSchristos 			content[i] = (i & 255);
1748585484eSchristos 	}
1758585484eSchristos 
1768585484eSchristos 	evhttp_set_cb(http, "/ind", http_basic_cb, NULL);
1778585484eSchristos 	fprintf(stderr, "/ind - basic content (memory copy)\n");
1788585484eSchristos 
1798585484eSchristos 	evhttp_set_cb(http, "/ref", http_ref_cb, NULL);
1808585484eSchristos 	fprintf(stderr, "/ref - basic content (reference)\n");
1818585484eSchristos 
1828585484eSchristos 	fprintf(stderr, "Serving %d bytes on port %d using %s\n",
1838585484eSchristos 	    (int)content_len, port,
1848585484eSchristos 	    use_iocp? "IOCP" : event_base_get_method(base));
1858585484eSchristos 
1868585484eSchristos 	evhttp_bind_socket(http, "0.0.0.0", port);
1878585484eSchristos 
188b8ecfcfeSchristos #ifdef _WIN32
1898585484eSchristos 	if (use_iocp) {
1908585484eSchristos 		struct timeval tv={99999999,0};
1918585484eSchristos 		event_base_loopexit(base, &tv);
1928585484eSchristos 	}
193b8ecfcfeSchristos #endif
1948585484eSchristos 	event_base_dispatch(base);
1958585484eSchristos 
196b8ecfcfeSchristos #ifdef _WIN32
197b8ecfcfeSchristos 	WSACleanup();
198b8ecfcfeSchristos #endif
199b8ecfcfeSchristos 
2008585484eSchristos 	/* NOTREACHED */
2018585484eSchristos 	return (0);
2028585484eSchristos }
203