From 745d946c83bf08bd8dc4b8550e31880501efaa1e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Petr=20P=C3=ADsa=C5=99?= Date: Thu, 13 Dec 2012 20:35:41 +0100 Subject: [PATCH] test: server: do socket I/O by call-backs This is necessary to inject TLS layer. --- test/simline/http.c | 20 +++++++++++++------- test/simline/http.h | 12 ++++++++++++ test/simline/server.c | 29 ++++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/test/simline/http.c b/test/simline/http.c index 9900209..d72b547 100644 --- a/test/simline/http.c +++ b/test/simline/http.c @@ -15,7 +15,7 @@ #include /* int8_t */ #include /* size_t, NULL */ #include /* isprint() */ -#include /* send(2) */ +#include /* MSG_NOSIGNAL for http_send_callback() */ /* Base64 encoder is part of the libb64 project, and has been placed in the public domain. @@ -230,6 +230,10 @@ static char *uri_decode(const char *coded) { } +/* Call-backs set by application */ +http_recv_callback_t http_recv_callback = NULL; +http_send_callback_t http_send_callback = NULL; + /* Read a line from HTTP socket. * @socket is descriptor to read from. * @line is auto-allocated just read line. Will be NULL if EOF has been @@ -288,8 +292,9 @@ static int http_read_line(int socket, char **line, } /* Read data */ - got = read(socket, *buffer + *buffer_used, *buffer_size - *buffer_used); - if (got == -1 && errno != EINTR) return HTTP_ERROR_CLIENT; + got = http_recv_callback(socket, *buffer + *buffer_used, + *buffer_size - *buffer_used, 0); + if (got == -1) return HTTP_ERROR_CLIENT; /* Check for EOF */ if (got == 0) return HTTP_ERROR_CLIENT; @@ -315,8 +320,8 @@ static int http_write_bulk(int socket, const void *data, size_t length) { if (data == NULL && length > 0) return HTTP_ERROR_SERVER; for (end = data + length; data != end; data += written, length -= written) { - written = send(socket, data, length, MSG_NOSIGNAL); - if (written == -1 && errno != EINTR) return HTTP_ERROR_CLIENT; + written = http_send_callback(socket, data, length, MSG_NOSIGNAL); + if (written == -1) return HTTP_ERROR_CLIENT; } return HTTP_ERROR_SUCCESS; @@ -396,8 +401,9 @@ static int http_read_bulk(int socket, void **data, size_t data_length, } /* Read data */ - got = read(socket, *buffer + *buffer_used, *buffer_size - *buffer_used); - if (got == -1 && errno != EINTR) return HTTP_ERROR_CLIENT; + got = http_recv_callback(socket, *buffer + *buffer_used, + *buffer_size - *buffer_used, 0); + if (got == -1) return HTTP_ERROR_CLIENT; /* Check for EOF */ if (got == 0) return HTTP_ERROR_CLIENT; diff --git a/test/simline/http.h b/test/simline/http.h index bdb2afd..b413e2a 100644 --- a/test/simline/http.h +++ b/test/simline/http.h @@ -3,6 +3,18 @@ #include +/* Call-back type for non-interrupting receving from socket. See recv(2). */ +typedef ssize_t (*http_recv_callback_t) (int socket, void *buffer, + size_t length, int flags); +/* Application must set this pointer. */ +extern http_recv_callback_t http_recv_callback; + +/* Call-back type for non-interrupting sending to socket. See send(2). */ +typedef ssize_t (*http_send_callback_t) (int socket, const void *buffer, + size_t length, int flags); +/* Application must set this pointer. */ +extern http_send_callback_t http_send_callback; + typedef enum { HTTP_ERROR_SERVER = -1, HTTP_ERROR_SUCCESS = 0, diff --git a/test/simline/server.c b/test/simline/server.c index 2fe350e..09facce 100644 --- a/test/simline/server.c +++ b/test/simline/server.c @@ -15,6 +15,7 @@ #include #include #include +#include /* For EINTR */ #include #include #include @@ -563,6 +564,29 @@ int server_out_of_order(int client_socket, } +/* Call-back for HTTP to receive data from socket + * API is equivalent to recv(2) except automatic interrupt handling. */ +static ssize_t recv_plain(int socket, void *buffer, size_t length, int flags) { + ssize_t retval; + do { + retval = recv(socket, buffer, length, flags); + } while (-1 == retval && EINTR == errno); + return retval; +} + + +/* Call-back for HTTP to sending data to socket + * API is equivalent to send(2) except automatic interrupt handling. */ +static ssize_t send_plain(int socket, const void *buffer, size_t length, + int flags) { + ssize_t retval; + do { + retval = send(socket, buffer, length, flags); + } while (-1 == retval && EINTR == errno); + return retval; +} + + /* Start sever in separate process. * @server_process is PID of forked server * @server_address is automatically allocated TCP address of listening server @@ -587,7 +611,10 @@ int start_server(pid_t *server_process, char **server_address, const void *server_arguments, const struct tls_authentication *tls) { int server_socket; int error; - + + http_recv_callback = recv_plain; + http_send_callback = send_plain; + if (server_address == NULL) { set_server_error("start_server(): Got invalid server_address pointer"); return -1; -- 2.11.4.GIT