dovecot-2.2: lib-http: Added a very dummy test-http-server

dovecot at dovecot.org dovecot at dovecot.org
Thu Jul 11 14:29:23 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/6d986d132fb8
changeset: 16605:6d986d132fb8
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Jul 11 14:29:05 2013 +0300
description:
lib-http: Added a very dummy test-http-server

diffstat:

 src/lib-http/Makefile.am        |   16 ++++-
 src/lib-http/test-http-server.c |  131 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 146 insertions(+), 1 deletions(-)

diffs (168 lines):

diff -r c55bd41133a2 -r 6d986d132fb8 src/lib-http/Makefile.am
--- a/src/lib-http/Makefile.am	Thu Jul 11 14:18:42 2013 +0300
+++ b/src/lib-http/Makefile.am	Thu Jul 11 14:29:05 2013 +0300
@@ -45,7 +45,8 @@
 	test-http-response-parser
 
 test_nocheck_programs = \
-	test-http-client
+	test-http-client \
+	test-http-server
 
 noinst_PROGRAMS = $(test_programs) $(test_nocheck_programs)
 
@@ -103,6 +104,19 @@
 	../lib-ssl-iostream/libssl_iostream.la \
 	$(test_deps)
 
+test_http_server_SOURCES = test-http-server.c
+test_http_server_LDFLAGS = -export-dynamic
+test_http_server_LDADD = \
+	libhttp.la \
+	../lib-dns/libdns.la \
+	../lib-ssl-iostream/libssl_iostream.la \
+	$(test_libs)
+test_http_server_DEPENDENCIES = \
+	libhttp.la \
+	../lib-dns/libdns.la \
+	../lib-ssl-iostream/libssl_iostream.la \
+	$(test_deps)
+
 check: check-am check-test
 check-test: all-am
 	for bin in $(test_programs); do \
diff -r c55bd41133a2 -r 6d986d132fb8 src/lib-http/test-http-server.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-http/test-http-server.c	Thu Jul 11 14:29:05 2013 +0300
@@ -0,0 +1,131 @@
+/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "str.h"
+#include "ioloop.h"
+#include "ostream.h"
+#include "connection.h"
+#include "http-date.h"
+#include "http-request-parser.h"
+
+static struct connection_list *clients;
+static int fd_listen;
+struct io *io_listen;
+
+struct client {
+	struct connection conn;
+	struct http_request_parser *parser;
+};
+
+static void client_destroy(struct connection *conn)
+{
+	struct client *client = (struct client *)conn;
+
+	http_request_parser_deinit(&client->parser);
+	connection_deinit(&client->conn);
+	i_free(client);
+}
+
+static int
+client_handle_request(struct client *client, struct http_request *request)
+{
+	string_t *str = t_str_new(128);
+
+	if (strcmp(request->method, "GET") != 0) {
+		o_stream_send_str(client->conn.output, "HTTP/1.1 501 Not Implemented\r\nAllow: GET\r\n\r\n");
+		return 0;
+	}
+	str_append(str, "HTTP/1.1 200 OK\r\n");
+	str_printfa(str, "Date: %s\r\n", http_date_create(ioloop_time));
+	str_printfa(str, "Content-Length: %d\r\n", (int)strlen(request->target));
+	str_append(str, "Content-Type: text/plain\r\n");
+	str_append(str, "\r\n");
+	str_append(str, request->target);
+	o_stream_send(client->conn.output, str_data(str), str_len(str));
+	return 0;
+}
+
+static void client_input(struct connection *conn)
+{
+	struct client *client = (struct client *)conn;
+	struct http_request *request;
+	const char *error;
+	int ret;
+
+	while ((ret = http_request_parse_next(client->parser, &request, &error)) > 0) {
+		if (client_handle_request(client, request) < 0 ||
+		    request->connection_close) {
+			client_destroy(conn);
+			return;
+		}
+	}
+	if (ret < 0) {
+		i_error("Client sent invalid request: %s", error);
+		client_destroy(conn);
+	}
+}
+
+static struct connection_settings client_set = {
+	.input_max_size = (size_t)-1,
+	.output_max_size = (size_t)-1,
+	.client = FALSE
+};
+
+static const struct connection_vfuncs client_vfuncs = {
+	.destroy = client_destroy,
+	.input = client_input
+};
+
+static void client_init(int fd)
+{
+	struct client *client;
+
+	client = i_new(struct client, 1);
+	connection_init_server(clients, &client->conn,
+			       "(http client)", fd, fd);
+	client->parser = http_request_parser_init(client->conn.input);
+}
+
+static void client_accept(void *context ATTR_UNUSED)
+{
+	int fd;
+
+	fd = net_accept(fd_listen, NULL, NULL);
+	if (fd == -1)
+		return;
+	if (fd == -2)
+		i_fatal("accept() failed: %m");
+
+	client_init(fd);
+}
+
+int main(int argc, char *argv[])
+{
+	struct ip_addr my_ip;
+	struct ioloop *ioloop;
+	unsigned int port;
+
+	lib_init();
+	if (argc < 2 || str_to_uint(argv[1], &port) < 0)
+		i_fatal("Port parameter missing");
+	if (argc < 3)
+		net_get_ip_any4(&my_ip);
+	else if (net_addr2ip(argv[2], &my_ip) < 0)
+		i_fatal("Invalid IP parameter");
+
+	ioloop = io_loop_create();
+	clients = connection_list_init(&client_set, &client_vfuncs);
+
+	fd_listen = net_listen(&my_ip, &port, 128);
+	if (fd_listen == -1)
+		i_fatal("listen(port=%u) failed: %m", port);
+	io_listen = io_add(fd_listen, IO_READ, client_accept, NULL);
+
+	io_loop_run(ioloop);
+
+	io_remove(&io_listen);
+	i_close_fd(&fd_listen);
+	connection_list_deinit(&clients);
+	io_loop_destroy(&ioloop);
+	lib_deinit();
+}


More information about the dovecot-cvs mailing list