test-http-payload.c revision baf3e87e186453fda13bd21f7cbcb2efc8492e8b
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/* Copyright (c) 2013-2016 Dovecot authors, see the included COPYING file */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include "lib.h"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include "str.h"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include "llist.h"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include "abspath.h"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include "hostpid.h"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include "ioloop.h"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include "istream.h"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include "ostream.h"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include "iostream-temp.h"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include "connection.h"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include "test-common.h"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include "http-url.h"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include "http-request.h"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include "http-server.h"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include "http-client.h"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include <sys/types.h>
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include <sys/stat.h>
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include <sys/wait.h>
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include <signal.h>
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include <fcntl.h>
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include <unistd.h>
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch#include <dirent.h>
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic bool debug = FALSE;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Boschstatic bool blocking = FALSE;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic bool request_100_continue = FALSE;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Boschstatic size_t read_server_partial = 0;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Boschstatic size_t read_client_partial = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic unsigned int test_max_pending = 200;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Boschstatic unsigned int client_ioloop_nesting = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic struct ip_addr bind_ip;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic in_port_t bind_port = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic int fd_listen = -1;
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Boschstatic pid_t server_pid = (pid_t)-1;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Boschstatic struct ioloop *ioloop_nested = NULL;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Boschstatic unsigned ioloop_nested_first = 0;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Boschstatic unsigned ioloop_nested_last = 0;
19f8621e1473269d6820988d84f815774c2c1053Stephan Boschstatic unsigned ioloop_nested_depth = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/*
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch * Test files
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic ARRAY_TYPE(const_string) files;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic pool_t files_pool;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_files_read_dir(const char *path)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch DIR *dirp;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* open the directory */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if ((dirp = opendir(path)) == NULL) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (errno == ENOENT || errno == EACCES)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test files: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to open directory %s: %m", path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* read entries */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch for (;;) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char *file;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct dirent *dp;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct stat st;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch errno = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if ((dp=readdir(dirp)) == NULL)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch break;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (*dp->d_name == '.')
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch continue;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch file = t_abspath_to(dp->d_name, path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (stat(file, &st) == 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (S_ISREG(st.st_mode)) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch file += 2; /* skip "./" */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch file = p_strdup(files_pool, file);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch array_append(&files, &file, 1);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch } else {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_files_read_dir(file);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (errno != 0)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test files: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to read directory %s: %m", path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* Close the directory */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (closedir(dirp) < 0)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_error("test files: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to close directory %s: %m", path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_files_init(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* initialize file array */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch files_pool = pool_alloconly_create
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (MEMPOOL_GROWING"http_server_request", 4096);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch p_array_init(&files, files_pool, 512);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* obtain all filenames */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_files_read_dir(".");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_files_deinit(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch pool_unref(&files_pool);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic struct istream *
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_file_open(const char *path,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch unsigned int *status_r, const char **reason_r)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch ATTR_NULL(2, 3)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch int fd;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (status_r != NULL)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch *status_r = 200;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (reason_r != NULL)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch *reason_r = "OK";
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fd = open(path, O_RDONLY);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (fd < 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test files: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "open(%s) failed: %m", path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch switch (errno) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch case EFAULT:
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch case ENOENT:
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (status_r != NULL)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch *status_r = 404;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (reason_r != NULL)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch *reason_r = "Not Found";
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch break;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch case EISDIR:
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch case EACCES:
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (status_r != NULL)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch *status_r = 403;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (reason_r != NULL)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch *reason_r = "Forbidden";
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch break;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch default:
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (status_r != NULL)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch *status_r = 500;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (reason_r != NULL)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch *reason_r = "Internal Server Error";
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return NULL;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi return i_stream_create_fd_autoclose(&fd, 40960);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/*
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch * Test server
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstruct client {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch pool_t pool;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct client *prev, *next;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_connection *http_conn;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch};
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstruct client_request {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct client *client;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_request *server_req;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char *path;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct istream *payload_input;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct ostream *payload_output;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct io *io;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch};
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic const struct http_server_callbacks http_callbacks;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic struct http_server *http_server;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic struct io *io_listen;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic struct client *clients;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/* location: /succes */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschclient_handle_success_request(struct client_request *creq)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_request *req = creq->server_req;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const struct http_request *hreq =
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_get(req);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_response *resp;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (strcmp(hreq->method, "GET") != 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_fail(req,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch 405, "Method Not Allowed");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch resp = http_server_response_create(req, 200, "OK");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_response_submit(resp);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/* location: /download/... */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschclient_handle_download_request(
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct client_request *creq,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char *path)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_request *req = creq->server_req;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const struct http_request *hreq =
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_get(req);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_response *resp;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char *fpath, *reason;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct istream *fstream;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct ostream *output;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch unsigned int status;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (strcmp(hreq->method, "GET") != 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_fail(req,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch 405, "Method Not Allowed");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fpath = t_strconcat(".", path, NULL);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test server: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "sending payload for %s", fpath);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fstream = test_file_open(fpath, &status, &reason);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (fstream == NULL) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_fail(req, status, reason);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch resp = http_server_response_create(req, 200, "OK");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_response_add_header(resp, "Content-Type", "text/plain");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (blocking) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch output = http_server_response_get_payload_output(resp, TRUE);
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen if (o_stream_send_istream(output, fstream) != OSTREAM_SEND_ISTREAM_RESULT_FINISHED) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test server: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to send blocking file payload");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test server: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "finished sending blocking payload for %s"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "(%"PRIuUOFF_T":%"PRIuUOFF_T")",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fpath, fstream->v_offset, output->offset);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch o_stream_close(output);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch o_stream_unref(&output);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch } else {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_response_set_payload(resp, fstream);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_response_submit(resp);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_unref(&fstream);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/* location: /echo */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschclient_request_read_echo_more(struct client_request *creq)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_response *resp;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct istream *payload_input;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen enum ostream_send_istream_result res;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch o_stream_set_max_buffer_size(creq->payload_output, IO_BLOCK_SIZE);
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen res = o_stream_send_istream(creq->payload_output, creq->payload_input);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch o_stream_set_max_buffer_size(creq->payload_output, (size_t)-1);
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen switch (res) {
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen case OSTREAM_SEND_ISTREAM_RESULT_FINISHED:
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen break;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT:
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT:
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT:
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen i_fatal("test server: echo: "
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen "Failed to read all echo payload [%s]", creq->path);
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT:
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen i_fatal("test server: echo: "
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen "Failed to write all echo payload [%s]", creq->path);
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch io_remove(&creq->io);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_unref(&creq->payload_input);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test server: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "finished receiving payload for %s", creq->path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch payload_input = iostream_temp_finish(&creq->payload_output, 4096);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch resp = http_server_response_create
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (creq->server_req, 200, "OK");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_response_add_header(resp, "Content-Type", "text/plain");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_response_set_payload(resp, payload_input);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_response_submit(resp);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_unref(&payload_input);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschclient_handle_echo_request(struct client_request *creq,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char *path)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_request *req = creq->server_req;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const struct http_request *hreq =
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_get(req);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_response *resp;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct ostream *payload_output;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch uoff_t size;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch creq->path = p_strdup
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (http_server_request_get_pool(req), path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (strcmp(hreq->method, "PUT") != 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_fail(req,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch 405, "Method Not Allowed");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch size = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (void)http_request_get_payload_size(hreq, &size);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (size == 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch resp = http_server_response_create
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (creq->server_req, 200, "OK");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_response_add_header(resp, "Content-Type", "text/plain");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_response_submit(resp);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch payload_output = iostream_temp_create
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch ("/tmp/test-http-server", 0);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (blocking) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct istream *payload_input;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch payload_input =
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_get_payload_input(req, TRUE);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch if (read_server_partial > 0) {
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch struct istream *partial =
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch i_stream_create_limit(payload_input, read_server_partial);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch i_stream_unref(&payload_input);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch payload_input = partial;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch }
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen if (o_stream_send_istream(payload_output, payload_input) != OSTREAM_SEND_ISTREAM_RESULT_FINISHED) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test server: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to receive blocking echo payload");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_unref(&payload_input);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch payload_input = iostream_temp_finish(&payload_output, 4096);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test server: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "finished receiving blocking payload for %s", path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch resp = http_server_response_create(req, 200, "OK");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_response_add_header(resp, "Content-Type", "text/plain");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch payload_output = http_server_response_get_payload_output(resp, TRUE);
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen if (o_stream_send_istream(payload_output, payload_input) != OSTREAM_SEND_ISTREAM_RESULT_FINISHED) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test server: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to send blocking echo payload");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test server: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "finished sending blocking payload for %s", path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_unref(&payload_input);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch o_stream_close(payload_output);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch o_stream_unref(&payload_output);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch } else {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch creq->payload_output = payload_output;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch creq->payload_input =
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_get_payload_input(req, FALSE);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch if (read_server_partial > 0) {
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch struct istream *partial =
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch i_stream_create_limit(creq->payload_input, read_server_partial);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch i_stream_unref(&creq->payload_input);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch creq->payload_input = partial;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch }
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch creq->io = io_add_istream(creq->payload_input,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client_request_read_echo_more, creq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client_request_read_echo_more(creq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/* request */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschhttp_server_request_destroyed(void *context);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic struct client_request *
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschclient_request_init(struct client *client,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_request *req)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct client_request *creq;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch pool_t pool = http_server_request_get_pool(req);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_ref(req);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch creq = p_new(pool, struct client_request, 1);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch creq->client = client;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch creq->server_req = req;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_set_destroy_callback(req,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_destroyed, creq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return creq;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void client_request_deinit(struct client_request **_creq)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct client_request *creq = *_creq;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_request *req = creq->server_req;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch *_creq = NULL;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (creq->io != NULL) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_unref(&creq->payload_input);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch io_remove(&creq->io);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_unref(&req);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschhttp_server_request_destroyed(void *context)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct client_request *creq =
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (struct client_request *)context;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client_request_deinit(&creq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschclient_handle_request(void *context,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_request *req)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const struct http_request *hreq =
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_get(req);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char *path = hreq->target.url->path, *p;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct client *client = (struct client *)context;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct client_request *creq;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test server: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "request method=`%s' path=`%s'", hreq->method, path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch creq = client_request_init(client, req);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (strcmp(path, "/success") == 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client_handle_success_request(creq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if ((p=strchr(path+1, '/')) == NULL) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_fail(req, 404, "Not found");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (strncmp(path, "/download", p-path) == 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client_handle_download_request(creq, p);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (strncmp(path, "/echo", p-path) == 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client_handle_echo_request(creq, p);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_fail(req, 404, "Not found");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/* client connection */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschclient_connection_destroy(void *context, const char *reason);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic const struct http_server_callbacks http_callbacks = {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch .connection_destroy = client_connection_destroy,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch .handle_request = client_handle_request
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch};
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void client_init(int fd)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct client *client;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch pool_t pool;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch net_set_nonblock(fd, TRUE);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch pool = pool_alloconly_create("client", 256);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client = p_new(pool, struct client, 1);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client->pool = pool;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client->http_conn = http_server_connection_create(http_server,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fd, fd, FALSE, &http_callbacks, client);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch DLLIST_PREPEND(&clients, client);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void client_deinit(struct client **_client)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct client *client = *_client;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch *_client = NULL;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch DLLIST_REMOVE(&clients, client);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (client->http_conn != NULL)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_connection_close(&client->http_conn, "deinit");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch pool_unref(&client->pool);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschclient_connection_destroy(void *context, const char *reason ATTR_UNUSED)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct client *client = context;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client->http_conn = NULL;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client_deinit(&client);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void client_accept(void *context ATTR_UNUSED)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch int fd;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* accept new client */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fd = net_accept(fd_listen, NULL, NULL);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (fd == -1)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (fd == -2) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test server: accept() failed: %m");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client_init(fd);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/* */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_server_init(const struct http_server_settings *server_set)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* open server socket */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch io_listen = io_add(fd_listen,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch IO_READ, client_accept, (void *)NULL);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server = http_server_init(server_set);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_server_deinit(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* close server socket */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch io_remove(&io_listen);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* deinitialize */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_deinit(&http_server);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/*
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch * Test client
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstruct test_client_request {
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch struct test_client_request *prev, *next;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch struct http_client_request *hreq;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct io *io;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct istream *payload;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct istream *file;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch unsigned int files_idx;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch};
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic struct http_client *http_client;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Boschstatic struct test_client_request *client_requests;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic unsigned int client_files_first, client_files_last;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Boschstatic struct test_client_request *
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Boschtest_client_request_new(void)
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch{
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch struct test_client_request *tcreq;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch tcreq = i_new(struct test_client_request, 1);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch DLLIST_PREPEND(&client_requests, tcreq);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch return tcreq;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch}
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_client_request_destroy(void *context)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct test_client_request *tcreq =
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (struct test_client_request *)context;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (tcreq->io != NULL)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch io_remove(&tcreq->io);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (tcreq->payload != NULL)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_unref(&tcreq->payload);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (tcreq->file != NULL)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_unref(&tcreq->file);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch DLLIST_REMOVE(&client_requests, tcreq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_free(tcreq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Boschstatic void
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Boschtest_client_requests_switch_ioloop(void)
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch{
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch struct test_client_request *tcreq;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch for (tcreq = client_requests; tcreq != NULL;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch tcreq = tcreq->next) {
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch if (tcreq->io != NULL)
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch tcreq->io = io_loop_move_io(&tcreq->io);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch if (tcreq->payload != NULL)
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch i_stream_switch_ioloop(tcreq->payload);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch }
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch}
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/* download */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_client_download_continue(void);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Boschtest_client_download_finished(unsigned int files_idx)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char **paths;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch unsigned int count;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch paths = array_get_modifiable(&files, &count);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch i_assert(files_idx < count);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(client_files_first < count);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch i_assert(paths[files_idx] != NULL);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch paths[files_idx] = NULL;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_client_download_continue();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_client_download_payload_input(struct test_client_request *tcreq)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct istream *payload = tcreq->payload;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const unsigned char *pdata, *fdata;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch size_t psize, fsize, pleft;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch unsigned int files_idx = tcreq->files_idx;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch off_t ret;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* read payload */
651f981ca065d2365bf2ea07b04318a5402f047aTimo Sirainen while ((ret=i_stream_read_more(payload, &pdata, &psize)) > 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "got data for [%u] (size=%d)",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->files_idx, (int)psize);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* compare with file on disk */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch pleft = psize;
651f981ca065d2365bf2ea07b04318a5402f047aTimo Sirainen while ((ret=i_stream_read_more
651f981ca065d2365bf2ea07b04318a5402f047aTimo Sirainen (tcreq->file, &fdata, &fsize)) > 0 && pleft > 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fsize = (fsize > pleft ? pleft : fsize);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (memcmp(pdata, fdata, fsize) != 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test client: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "received data does not match file "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "(%"PRIuUOFF_T":%"PRIuUOFF_T")",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch payload->v_offset, tcreq->file->v_offset);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_skip(tcreq->file, fsize);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch pleft -= fsize;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch pdata += fsize;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (ret < 0 && tcreq->file->stream_errno != 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test client: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to read file: %s", i_stream_get_error(tcreq->file));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_skip(payload, psize);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (ret == 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "need more data for [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->files_idx);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* we will be called again for this request */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch } else {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (void)i_stream_read(tcreq->file);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (payload->stream_errno != 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test client: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to read request payload: %s",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_get_error(payload));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch } if (i_stream_have_bytes_left(tcreq->file)) {
651f981ca065d2365bf2ea07b04318a5402f047aTimo Sirainen if (i_stream_read_more(tcreq->file, &fdata, &fsize) <= 0)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fsize = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test client: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "payload ended prematurely "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "(at least %"PRIuSIZE_T" bytes left)", fsize);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch } else if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "finished request for [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->files_idx);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* dereference payload stream; finishes the request */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->payload = NULL;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch io_remove(&tcreq->io); /* holds a reference too */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_unref(&payload);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch /* finished */
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch test_client_download_finished(files_idx);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_client_download_response(const struct http_response *resp,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct test_client_request *tcreq)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char **paths;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char *path;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch unsigned int count, status;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct istream *fstream;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char *reason;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "got response for [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->files_idx);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch paths = array_get_modifiable(&files, &count);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(tcreq->files_idx < count);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(client_files_first < count);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch path = paths[tcreq->files_idx];
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(path != NULL);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "path for [%u]: %s",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->files_idx, path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fstream = test_file_open(path, &status, &reason);
6eeed94a59ef11b7645adb77a121e04c01849e78Aki Tuomi i_assert(fstream != NULL);
6eeed94a59ef11b7645adb77a121e04c01849e78Aki Tuomi
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (status != resp->status) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test client: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "got wrong response for %s: %u %s (expected: %u %s)",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch path, resp->status, resp->reason, status, reason);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (resp->status / 100 != 2) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "HTTP request for %s failed: %u %s",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch path, resp->status, resp->reason);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_unref(&fstream);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch test_client_download_finished(tcreq->files_idx);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (resp->payload == NULL) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "no payload for %s [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch path, tcreq->files_idx);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_unref(&fstream);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch test_client_download_finished(tcreq->files_idx);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(fstream != NULL);
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch if (read_client_partial == 0) {
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch i_stream_ref(resp->payload);
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch tcreq->payload = resp->payload;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch tcreq->file = fstream;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch } else {
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch struct istream *payload = resp->payload;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch tcreq->payload = i_stream_create_limit
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch (payload, read_client_partial);
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch tcreq->file = i_stream_create_limit
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch (fstream, read_client_partial);
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch i_stream_unref(&fstream);
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch tcreq->io = io_add_istream(tcreq->payload,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_client_download_payload_input, tcreq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_client_download_payload_input(tcreq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_client_download_continue(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct test_client_request *tcreq;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_client_request *hreq;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char *const *paths;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch unsigned int count;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch paths = array_get(&files, &count);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(client_files_first <= count);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(client_files_last <= count);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(client_files_first <= client_files_last);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch for (; client_files_first < client_files_last &&
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch paths[client_files_first] == NULL; client_files_first++)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "received until [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client_files_first-1);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (client_files_first >= count) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch io_loop_stop(current_ioloop);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch for (; client_files_last < count &&
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (client_files_last - client_files_first) < test_max_pending;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client_files_last++) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char *path = paths[client_files_last];
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch tcreq = test_client_request_new();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->files_idx = client_files_last;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: download: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "retrieving %s [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch path, tcreq->files_idx);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch hreq = tcreq->hreq = http_client_request(http_client,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "GET", net_ip2addr(&bind_ip),
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch t_strconcat("/download/", path, NULL),
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_client_download_response, tcreq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_request_set_port(hreq, bind_port);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_request_set_destroy_callback(hreq,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_client_request_destroy, tcreq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_request_submit(hreq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_client_download(const struct http_client_settings *client_set)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* create client */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client = http_client_init(client_set);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* start querying server */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client_files_first = client_files_last = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_client_download_continue();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/* echo */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_client_echo_continue(void);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Boschtest_client_echo_finished(unsigned int files_idx)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char **paths;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch unsigned int count;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch paths = array_get_modifiable(&files, &count);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch i_assert(files_idx < count);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(client_files_first < count);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch i_assert(paths[files_idx] != NULL);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch paths[files_idx] = NULL;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_client_echo_continue();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_client_echo_payload_input(struct test_client_request *tcreq)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct istream *payload = tcreq->payload;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const unsigned char *pdata, *fdata;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch size_t psize, fsize, pleft;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch unsigned int files_idx = tcreq->files_idx;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch off_t ret;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* read payload */
651f981ca065d2365bf2ea07b04318a5402f047aTimo Sirainen while ((ret=i_stream_read_more(payload, &pdata, &psize)) > 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "got data for [%u] (size=%d)",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->files_idx, (int)psize);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* compare with file on disk */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch pleft = psize;
651f981ca065d2365bf2ea07b04318a5402f047aTimo Sirainen while ((ret=i_stream_read_more
651f981ca065d2365bf2ea07b04318a5402f047aTimo Sirainen (tcreq->file, &fdata, &fsize)) > 0 && pleft > 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fsize = (fsize > pleft ? pleft : fsize);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (memcmp(pdata, fdata, fsize) != 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test client: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "received data does not match file "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "(%"PRIuUOFF_T":%"PRIuUOFF_T")",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch payload->v_offset, tcreq->file->v_offset);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_skip(tcreq->file, fsize);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch pleft -= fsize;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch pdata += fsize;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (ret < 0 && tcreq->file->stream_errno != 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test client: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to read file: %s", i_stream_get_error(tcreq->file));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_skip(payload, psize);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (ret == 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "need more data for [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->files_idx);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* we will be called again for this request */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch } else {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (void)i_stream_read(tcreq->file);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (payload->stream_errno != 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test client: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to read request payload: %s",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_get_error(payload));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch } if (i_stream_have_bytes_left(tcreq->file)) {
651f981ca065d2365bf2ea07b04318a5402f047aTimo Sirainen if (i_stream_read_more(tcreq->file, &fdata, &fsize) <= 0)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fsize = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test client: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "payload ended prematurely "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "(at least %"PRIuSIZE_T" bytes left)", fsize);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch } else if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "finished request for [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->files_idx);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* dereference payload stream; finishes the request */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->payload = NULL;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch io_remove(&tcreq->io); /* holds a reference too */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_unref(&payload);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch /* finished */
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch test_client_echo_finished(files_idx);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_client_echo_response(const struct http_response *resp,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct test_client_request *tcreq)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char **paths;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char *path;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch unsigned int count, status;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct istream *fstream;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "got response for [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->files_idx);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch paths = array_get_modifiable(&files, &count);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(tcreq->files_idx < count);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(client_files_first < count);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch path = paths[tcreq->files_idx];
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(path != NULL);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "path for [%u]: %s",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->files_idx, path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (resp->status / 100 != 2) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test client: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "HTTP request for %s failed: %u %s",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch path, resp->status, resp->reason);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fstream = test_file_open(path, &status, NULL);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (fstream == NULL) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("test client: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to open %s", path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch if (read_server_partial > 0) {
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch struct istream *partial = i_stream_create_limit
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch (fstream, read_server_partial);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch i_stream_unref(&fstream);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch fstream = partial;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch }
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (resp->payload == NULL) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch // FIXME: check file is empty
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "no payload for %s [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch path, tcreq->files_idx);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_unref(&fstream);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch test_client_echo_finished(tcreq->files_idx);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(fstream != NULL);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->file = fstream;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_ref(resp->payload);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->payload = resp->payload;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->io = io_add_istream(resp->payload,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_client_echo_payload_input, tcreq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_client_echo_payload_input(tcreq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_client_echo_continue(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct test_client_request *tcreq;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_client_request *hreq;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char **paths;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch unsigned int count, first_submitted;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch paths = array_get_modifiable(&files, &count);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(client_files_first <= count);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(client_files_last <= count);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(client_files_first <= client_files_last);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch for (; client_files_first < client_files_last &&
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch paths[client_files_first] == NULL; client_files_first++);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: echo: "
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch "received until [%u/%u]", client_files_first-1, count);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch }
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch if (debug && client_files_first < count) {
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch const char *path = paths[client_files_first];
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch i_debug("test client: echo: "
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch "next blocking: %s [%d]",
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch (path == NULL ? "none" : path),
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch client_files_first);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (client_files_first >= count) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch io_loop_stop(current_ioloop);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch return;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch first_submitted = client_files_last;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch for (; client_files_last < count &&
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (client_files_last - client_files_first) < test_max_pending;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client_files_last++) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct istream *fstream;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char *path = paths[client_files_last];
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fstream = test_file_open(path, NULL, NULL);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (fstream == NULL) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch paths[client_files_last] = NULL;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "skipping %s [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch path, client_files_last);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch continue;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("test client: echo: "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "retrieving %s [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch path, client_files_last);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch tcreq = test_client_request_new();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch tcreq->files_idx = client_files_last;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch hreq = tcreq->hreq = http_client_request(http_client,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "PUT", net_ip2addr(&bind_ip),
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch t_strconcat("/echo/", path, NULL),
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_client_echo_response, tcreq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_request_set_port(hreq, bind_port);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_request_set_payload
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (hreq, fstream, request_100_continue);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_request_set_destroy_callback(hreq,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_client_request_destroy, tcreq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_request_submit(hreq);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_stream_unref(&fstream);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch /* run nested ioloop (if requested) if new requests cross a nesting
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch boundary */
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch if (ioloop_nested != NULL) {
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch unsigned int i;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch i_assert(ioloop_nested_first <= count);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch i_assert(ioloop_nested_last <= count);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch for (i = ioloop_nested_first; i < ioloop_nested_last; i++) {
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch if (paths[i] != NULL) {
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch if (debug) {
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch i_debug("test client: "
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch "not leaving ioloop [%u]", i);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch }
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch break;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch }
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch }
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch if (i == ioloop_nested_last)
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch io_loop_stop(ioloop_nested);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch } else if (client_ioloop_nesting > 0 &&
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch ((client_files_last / client_ioloop_nesting) !=
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch (first_submitted / client_ioloop_nesting)) ) {
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch struct ioloop *prev_ioloop = current_ioloop;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch ioloop_nested_first = first_submitted;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch ioloop_nested_last = first_submitted + client_ioloop_nesting;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch if (ioloop_nested_last > client_files_last)
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch ioloop_nested_last = client_files_last;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch if (debug) {
19f8621e1473269d6820988d84f815774c2c1053Stephan Bosch i_debug("test client: echo: entering ioloop for %u...%u (depth=%u)",
19f8621e1473269d6820988d84f815774c2c1053Stephan Bosch ioloop_nested_first, ioloop_nested_last, ioloop_nested_depth);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch }
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
19f8621e1473269d6820988d84f815774c2c1053Stephan Bosch ioloop_nested_depth++;
19f8621e1473269d6820988d84f815774c2c1053Stephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch ioloop_nested = io_loop_create();
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch http_client_switch_ioloop(http_client);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch test_client_requests_switch_ioloop();
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch io_loop_run(ioloop_nested);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch io_loop_set_current(prev_ioloop);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch http_client_switch_ioloop(http_client);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch test_client_requests_switch_ioloop();
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch io_loop_set_current(ioloop_nested);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch io_loop_destroy(&ioloop_nested);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch ioloop_nested = NULL;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
19f8621e1473269d6820988d84f815774c2c1053Stephan Bosch ioloop_nested_depth--;
19f8621e1473269d6820988d84f815774c2c1053Stephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch if (debug) {
19f8621e1473269d6820988d84f815774c2c1053Stephan Bosch i_debug("test client: echo: leaving ioloop for %u...%u (depth=%u)",
19f8621e1473269d6820988d84f815774c2c1053Stephan Bosch ioloop_nested_first, ioloop_nested_last, ioloop_nested_depth);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch }
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch ioloop_nested_first = ioloop_nested_last = 0;
0873f750d44a45e027c5f770f1619977ad676f18Stephan Bosch
0873f750d44a45e027c5f770f1619977ad676f18Stephan Bosch if (client_files_first >= count) {
0873f750d44a45e027c5f770f1619977ad676f18Stephan Bosch io_loop_stop(current_ioloop);
0873f750d44a45e027c5f770f1619977ad676f18Stephan Bosch return;
0873f750d44a45e027c5f770f1619977ad676f18Stephan Bosch }
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_client_echo(const struct http_client_settings *client_set)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* create client */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client = http_client_init(client_set);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* start querying server */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client_files_first = client_files_last = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_client_echo_continue();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/* cleanup */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_client_deinit(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_deinit(&http_client);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/*
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch * Tests
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_open_server_fd(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (fd_listen != -1)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_close_fd(&fd_listen);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fd_listen = net_listen(&bind_ip, &bind_port, 128);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (fd_listen == -1) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("listen(%s:%u) failed: %m",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch net_ip2addr(&bind_ip), bind_port);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Boschstatic void test_server_kill(void)
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch{
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch if (server_pid != (pid_t)-1) {
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch (void)kill(server_pid, SIGKILL);
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch (void)waitpid(server_pid, NULL, 0);
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch }
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch server_pid = (pid_t)-1;
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch}
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_run_client_server(
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const struct http_client_settings *client_set,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const struct http_server_settings *server_set,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch void (*client_init)(const struct http_client_settings *client_set))
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct ioloop *ioloop;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_open_server_fd();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch if ((server_pid = fork()) == (pid_t)-1)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_fatal("fork() failed: %m");
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch if (server_pid == 0) {
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch server_pid = (pid_t)-1;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch hostpid_init();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("server: PID=%s", my_pid);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* child: server */
d9a7e950a9cd21f2b4a90ec7759fca9e8fcc7995Timo Sirainen ioloop_nested = NULL;
19f8621e1473269d6820988d84f815774c2c1053Stephan Bosch ioloop_nested_depth = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch ioloop = io_loop_create();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_server_init(server_set);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch io_loop_run(ioloop);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_server_deinit();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch io_loop_destroy(&ioloop);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_close_fd(&fd_listen);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch } else {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (debug)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_debug("client: PID=%s", my_pid);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_close_fd(&fd_listen);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* parent: client */
d9a7e950a9cd21f2b4a90ec7759fca9e8fcc7995Timo Sirainen ioloop_nested = NULL;
19f8621e1473269d6820988d84f815774c2c1053Stephan Bosch ioloop_nested_depth = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch ioloop = io_loop_create();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client_init(client_set);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch io_loop_run(ioloop);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_client_deinit();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch io_loop_destroy(&ioloop);
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch test_server_kill();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch }
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_run_sequential(
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch void (*client_init)(const struct http_client_settings *client_set))
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_settings http_server_set;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_client_settings http_client_set;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* download files from blocking server */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* server settings */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch memset(&http_server_set, 0, sizeof(http_server_set));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_set.max_pipelined_requests = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_set.debug = debug;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_set.request_limits.max_payload_size = (uoff_t)-1;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* client settings */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch memset(&http_client_set, 0, sizeof(http_client_set));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.max_idle_time_msecs = 5*1000;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.max_parallel_connections = 1;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.max_pipelined_requests = 1;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.max_redirects = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.max_attempts = 1;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.debug = debug;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_files_init();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_client_server
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (&http_client_set, &http_server_set, client_init);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_files_deinit();
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_out("sequential", TRUE);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_run_pipeline(
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch void (*client_init)(const struct http_client_settings *client_set))
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_settings http_server_set;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_client_settings http_client_set;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* download files from blocking server */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* server settings */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch memset(&http_server_set, 0, sizeof(http_server_set));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_set.max_pipelined_requests = 4;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_set.debug = debug;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_set.request_limits.max_payload_size = (uoff_t)-1;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* client settings */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch memset(&http_client_set, 0, sizeof(http_client_set));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.max_idle_time_msecs = 5*1000;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.max_parallel_connections = 1;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch http_client_set.max_pipelined_requests = 8;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.max_redirects = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.max_attempts = 1;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.debug = debug;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_files_init();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_client_server
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (&http_client_set, &http_server_set, client_init);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_files_deinit();
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_out("pipeline", TRUE);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_run_parallel(
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch void (*client_init)(const struct http_client_settings *client_set))
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_settings http_server_set;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_client_settings http_client_set;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* download files from blocking server */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* server settings */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch memset(&http_server_set, 0, sizeof(http_server_set));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_set.max_pipelined_requests = 4;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_set.debug = debug;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_set.request_limits.max_payload_size = (uoff_t)-1;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* client settings */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch memset(&http_client_set, 0, sizeof(http_client_set));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.max_idle_time_msecs = 5*1000;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.max_parallel_connections = 40;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch http_client_set.max_pipelined_requests = 8;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.max_redirects = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.max_attempts = 1;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.debug = debug;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_files_init();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_client_server
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (&http_client_set, &http_server_set, client_init);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_files_deinit();
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_out("parallel", TRUE);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_download_server_nonblocking(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_begin("http payload download (server non-blocking)");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch blocking = FALSE;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch request_100_continue = FALSE;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch read_server_partial = 0;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch client_ioloop_nesting = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_sequential(test_client_download);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_pipeline(test_client_download);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_parallel(test_client_download);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_end();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_download_server_blocking(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_begin("http payload download (server blocking)");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch blocking = TRUE;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch request_100_continue = FALSE;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch read_server_partial = 0;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch client_ioloop_nesting = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_sequential(test_client_download);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_pipeline(test_client_download);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_parallel(test_client_download);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_end();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_echo_server_nonblocking(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_begin("http payload echo (server non-blocking)");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch blocking = FALSE;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch request_100_continue = FALSE;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch read_server_partial = 0;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch client_ioloop_nesting = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_sequential(test_client_echo);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_pipeline(test_client_echo);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_parallel(test_client_echo);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_end();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_echo_server_blocking(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_begin("http payload echo (server blocking)");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch blocking = TRUE;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch request_100_continue = FALSE;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch read_server_partial = 0;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch client_ioloop_nesting = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_sequential(test_client_echo);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_pipeline(test_client_echo);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_parallel(test_client_echo);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_end();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_echo_server_nonblocking_sync(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_begin("http payload echo (server non-blocking; 100-continue)");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch blocking = FALSE;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch request_100_continue = TRUE;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch read_server_partial = 0;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch client_ioloop_nesting = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_sequential(test_client_echo);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_pipeline(test_client_echo);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_parallel(test_client_echo);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_end();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_echo_server_blocking_sync(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_begin("http payload echo (server blocking; 100-continue)");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch blocking = TRUE;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch request_100_continue = TRUE;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch read_server_partial = 0;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch client_ioloop_nesting = 0;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_sequential(test_client_echo);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_pipeline(test_client_echo);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run_parallel(test_client_echo);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_end();
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Boschstatic void test_echo_server_nonblocking_partial(void)
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch{
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_begin("http payload echo (server non-blocking; partial short)");
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch blocking = FALSE;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch request_100_continue = FALSE;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch read_server_partial = 1024;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch client_ioloop_nesting = 0;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_run_sequential(test_client_echo);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_run_pipeline(test_client_echo);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_run_parallel(test_client_echo);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_end();
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_begin("http payload echo (server non-blocking; partial long)");
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch read_server_partial = IO_BLOCK_SIZE + 1024;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_run_sequential(test_client_echo);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_run_pipeline(test_client_echo);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_run_parallel(test_client_echo);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_end();
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch}
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Boschstatic void test_echo_server_blocking_partial(void)
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch{
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_begin("http payload echo (server blocking; partial short)");
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch blocking = TRUE;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch request_100_continue = FALSE;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch read_server_partial = 1024;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch client_ioloop_nesting = 0;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_run_sequential(test_client_echo);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_run_pipeline(test_client_echo);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_run_parallel(test_client_echo);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_end();
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_begin("http payload echo (server blocking; partial long)");
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch read_server_partial = IO_BLOCK_SIZE + 1024;
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_run_sequential(test_client_echo);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_run_pipeline(test_client_echo);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_run_parallel(test_client_echo);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_end();
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch}
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Boschstatic void test_download_client_partial(void)
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch{
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch test_begin("http payload download (client partial)");
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch blocking = FALSE;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch request_100_continue = FALSE;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch read_server_partial = 0;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch read_client_partial = 1024;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch client_ioloop_nesting = 0;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch test_run_sequential(test_client_download);
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch test_run_pipeline(test_client_download);
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch test_run_parallel(test_client_download);
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch test_end();
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch test_begin("http payload download (client partial long)");
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch blocking = FALSE;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch request_100_continue = FALSE;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch read_server_partial = 0;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch read_client_partial = IO_BLOCK_SIZE + 1024;
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch test_run_sequential(test_client_download);
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch test_run_pipeline(test_client_download);
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch test_run_parallel(test_client_download);
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch test_end();
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch}
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Boschstatic void test_download_client_nested_ioloop(void)
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch{
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch test_begin("http payload echo (client nested ioloop)");
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch blocking = FALSE;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch request_100_continue = FALSE;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch read_server_partial = 0;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch read_client_partial = 0;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch client_ioloop_nesting = 10;
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch test_run_parallel(test_client_echo);
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch test_end();
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch}
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch
baf3e87e186453fda13bd21f7cbcb2efc8492e8bTimo Sirainenstatic void (*const test_functions[])(void) = {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_download_server_nonblocking,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_download_server_blocking,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_echo_server_nonblocking,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_echo_server_blocking,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_echo_server_nonblocking_sync,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_echo_server_blocking_sync,
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_echo_server_nonblocking_partial,
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_echo_server_blocking_partial,
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch test_download_client_partial,
b44c460e198dd3dd8be29304d4a3cb5e071894dcStephan Bosch test_download_client_nested_ioloop,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch NULL
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch};
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/*
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch * Main
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Boschvolatile sig_atomic_t terminating = 0;
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Boschstatic void
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Boschtest_signal_handler(int signo)
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch{
23bdbb7b1831785c6ba6df190f6369da882d2b9dTimo Sirainen if (terminating != 0)
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch raise(signo);
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch terminating = 1;
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch /* make sure we don't leave any pesky children alive */
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch test_server_kill();
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch (void)signal(signo, SIG_DFL);
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch raise(signo);
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch}
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Boschstatic void test_atexit(void)
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch{
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch test_server_kill();
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch}
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch
844b0294f9bfc721e37782cada248394b531cea3Stephan Boschint main(int argc, char *argv[])
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch{
844b0294f9bfc721e37782cada248394b531cea3Stephan Bosch int c;
844b0294f9bfc721e37782cada248394b531cea3Stephan Bosch
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch atexit(test_atexit);
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch (void)signal(SIGCHLD, SIG_IGN);
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch (void)signal(SIGTERM, test_signal_handler);
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch (void)signal(SIGQUIT, test_signal_handler);
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch (void)signal(SIGINT, test_signal_handler);
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch (void)signal(SIGSEGV, test_signal_handler);
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch (void)signal(SIGABRT, test_signal_handler);
7362ba25c47c19e2dd9e61f066b487fa1f204c8aStephan Bosch
844b0294f9bfc721e37782cada248394b531cea3Stephan Bosch while ((c = getopt(argc, argv, "D")) > 0) {
844b0294f9bfc721e37782cada248394b531cea3Stephan Bosch switch (c) {
844b0294f9bfc721e37782cada248394b531cea3Stephan Bosch case 'D':
844b0294f9bfc721e37782cada248394b531cea3Stephan Bosch debug = TRUE;
844b0294f9bfc721e37782cada248394b531cea3Stephan Bosch break;
844b0294f9bfc721e37782cada248394b531cea3Stephan Bosch default:
844b0294f9bfc721e37782cada248394b531cea3Stephan Bosch i_fatal("Usage: %s [-D]", argv[0]);
844b0294f9bfc721e37782cada248394b531cea3Stephan Bosch }
844b0294f9bfc721e37782cada248394b531cea3Stephan Bosch }
844b0294f9bfc721e37782cada248394b531cea3Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* listen on localhost */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch memset(&bind_ip, 0, sizeof(bind_ip));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch bind_ip.family = AF_INET;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch bind_ip.u.ip4.s_addr = htonl(INADDR_LOOPBACK);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_run(test_functions);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch}