]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
gnutls-serv: add --httpdata option to respond with fixed sized data
authorDaiki Ueno <dueno@redhat.com>
Fri, 7 Jun 2019 12:54:58 +0000 (14:54 +0200)
committerDaiki Ueno <dueno@redhat.com>
Wed, 19 Jun 2019 13:10:50 +0000 (15:10 +0200)
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>
src/serv-args.def
src/serv.c

index 1e770a5f51e519a3ebda75a9a15929f0b96b619a..a2e9d1c6f833989f1d29aaba5cff51d322358a5f 100644 (file)
@@ -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
index ced393822f28ca665d78f724a0b0dc3f79f091b7..cc68abb5095ea3d46188f932933e49070c948e9d 100644 (file)
@@ -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 */