summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <dueno@redhat.com>2019-06-07 14:54:58 +0200
committerDaiki Ueno <dueno@redhat.com>2019-06-19 15:10:50 +0200
commit5f8a670e134bb3642d717b1bffcdc49b03e5f744 (patch)
treecb4dd67e7d6762874c4d4d5750297d2d3ef4cde2
parent70ed45cfe52d0a8f37f3527fcdca28b36c45797d (diff)
downloadgnutls-5f8a670e134bb3642d717b1bffcdc49b03e5f744.tar.gz
gnutls-serv: add --httpdata option to respond with fixed sized data
By default, the gnutls-server --http responds with the connection information. While this is useful for manual testing, fixed content would be more desirable for automated testing. Signed-off-by: Daiki Ueno <dueno@redhat.com>
-rw-r--r--src/serv-args.def8
-rw-r--r--src/serv.c48
2 files changed, 55 insertions, 1 deletions
diff --git a/src/serv-args.def b/src/serv-args.def
index 1e770a5f51..a2e9d1c6f8 100644
--- a/src/serv-args.def
+++ b/src/serv-args.def
@@ -340,6 +340,14 @@ flag = {
doc = "";
};
+flag = {
+ name = httpdata;
+ arg-type = file;
+ file-exists = yes;
+ descrip = "The data used as HTTP response";
+ doc = "";
+};
+
doc-section = {
ds-type = 'SEE ALSO'; // or anything else
ds-format = 'texi'; // or texi or mdoc format
diff --git a/src/serv.c b/src/serv.c
index ced393822f..cc68abb509 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -89,6 +89,7 @@ unsigned alpn_protos_size = 0;
gnutls_datum_t session_ticket_key;
gnutls_anti_replay_t anti_replay;
int record_max_size;
+const char *http_data_file = NULL;
static void tcp_server(const char *name, int port);
/* end of globals */
@@ -750,6 +751,45 @@ static char *peer_print_info(gnutls_session_t session, int *ret_length,
return http_buffer;
}
+static char *peer_print_data(gnutls_session_t session, int *ret_length)
+{
+ gnutls_datum_t data;
+ char *http_buffer;
+ size_t len;
+ int ret;
+
+ ret = gnutls_load_file(http_data_file, &data);
+ if (ret < 0) {
+ ret = asprintf(&http_buffer,
+ "HTTP/1.0 404 Not Found\r\n"
+ "Content-type: text/html\r\n"
+ "\r\n"
+ "<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD>\n"
+ "<BODY><H1>Couldn't read %s</H1></BODY></HTML>\n\n",
+ http_data_file);
+ if (ret < 0)
+ return NULL;
+
+ *ret_length = strlen(http_buffer);
+ return http_buffer;
+ }
+
+ ret = asprintf(&http_buffer,
+ "HTTP/1.0 200 OK\r\n"
+ "Content-Type: application/octet-stream\r\n"
+ "Content-Length: %u\r\n"
+ "\r\n",
+ data.size);
+ if (ret < 0)
+ return NULL;
+ len = ret;
+ http_buffer = realloc(http_buffer, len + data.size);
+ memcpy(&http_buffer[len], data.data, data.size);
+ gnutls_free(data.data);
+ *ret_length = len + data.size;
+ return http_buffer;
+}
+
const char *human_addr(const struct sockaddr *sa, socklen_t salen,
char *buf, size_t buflen)
{
@@ -991,7 +1031,10 @@ get_response(gnutls_session_t session, char *request,
}
/* *response = peer_print_info(session, request+4, h, response_length); */
if (http != 0) {
- *response = peer_print_info(session, response_length, h);
+ if (http_data_file == NULL)
+ *response = peer_print_info(session, response_length, h);
+ else
+ *response = peer_print_data(session, response_length);
} else {
int ret;
strip(request);
@@ -1791,6 +1834,9 @@ static void cmd_parser(int argc, char **argv)
if (HAVE_OPT(SNI_HOSTNAME_FATAL))
sni_hostname_fatal = 1;
+ if (HAVE_OPT(HTTPDATA))
+ http_data_file = OPT_ARG(HTTPDATA);
+
}
/* session resuming support */