diff options
author | Daiki Ueno <dueno@redhat.com> | 2019-06-07 14:54:58 +0200 |
---|---|---|
committer | Daiki Ueno <dueno@redhat.com> | 2019-06-19 15:10:50 +0200 |
commit | 5f8a670e134bb3642d717b1bffcdc49b03e5f744 (patch) | |
tree | cb4dd67e7d6762874c4d4d5750297d2d3ef4cde2 | |
parent | 70ed45cfe52d0a8f37f3527fcdca28b36c45797d (diff) | |
download | gnutls-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.def | 8 | ||||
-rw-r--r-- | src/serv.c | 48 |
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 */ |