diff options
author | Matt Caswell <matt@openssl.org> | 2023-08-14 16:32:44 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2023-08-25 11:42:51 +0100 |
commit | f6225f4f692ab45c0e891f83a7782a7dcd211204 (patch) | |
tree | 8b67ee21b8e5644c902c41eb7fd76ac38f4cf684 /util/quicserver.c | |
parent | 584140fa4b0a037c85b58722a08ba6fd0ee086ce (diff) |
Update quicserver to be able to handle multiple streams
We extend quicserver so that it can handle multiple requests with an
HTTP request on each one. If a uni-directional stream comes in we create
a uni-directional stream for the response
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21765)
Diffstat (limited to 'util/quicserver.c')
-rw-r--r-- | util/quicserver.c | 102 |
1 files changed, 66 insertions, 36 deletions
diff --git a/util/quicserver.c b/util/quicserver.c index 25ac21691f..c25128eaf6 100644 --- a/util/quicserver.c +++ b/util/quicserver.c @@ -149,9 +149,16 @@ int main(int argc, char *argv[]) const char reqterm[] = { '\r', '\n', '\r', '\n' }; - const char *msg = "Hello world\n"; + const char *response[] = { + "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n<!DOCTYPE html>\n<html>\n<body>Hello world</body>\n</html>\n", + "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n<!DOCTYPE html>\n<html>\n<body>Hello again</body>\n</html>\n", + "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n<!DOCTYPE html>\n<html>\n<body>Another response</body>\n</html>\n", + "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n<!DOCTYPE html>\n<html>\n<body>A message</body>\n</html>\n", + }; unsigned char alpn[] = { 8, 'h', 't', 't', 'p', '/', '1', '.', '0' }; int first = 1; + uint64_t streamid; + size_t respnum = 0; bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); if (argc == 0 || bio_err == NULL) @@ -212,49 +219,72 @@ int main(int argc, char *argv[]) if (trace) ossl_quic_tserver_set_msg_callback(qtserv, SSL_trace, bio_err); - /* Read the request */ - do { - if (first) - first = 0; - else - wait_for_activity(qtserv); - + /* Wait for handshake to complete */ + ossl_quic_tserver_tick(qtserv); + while(!ossl_quic_tserver_is_handshake_confirmed(qtserv)) { + wait_for_activity(qtserv); ossl_quic_tserver_tick(qtserv); + } - if (ossl_quic_tserver_read(qtserv, 0, reqbuf + reqbytes, - sizeof(reqbuf) - reqbytes, - &numbytes)) { - if (numbytes > 0) - fwrite(reqbuf + reqbytes, 1, numbytes, stdout); - reqbytes += numbytes; + for (;; respnum++) { + if (respnum >= OSSL_NELEM(response)) + goto end; + /* Wait for an incoming stream */ + do { + streamid = ossl_quic_tserver_pop_incoming_stream(qtserv); + if (streamid == UINT64_MAX) + wait_for_activity(qtserv); + ossl_quic_tserver_tick(qtserv); + if (ossl_quic_tserver_is_terminated(qtserv)) { + /* Assume we finished everything the clients wants from us */ + ret = EXIT_SUCCESS; + goto end; + } + } while(streamid == UINT64_MAX); + + /* Read the request */ + do { + if (first) + first = 0; + else + wait_for_activity(qtserv); + + ossl_quic_tserver_tick(qtserv); + + if (ossl_quic_tserver_read(qtserv, streamid, reqbuf + reqbytes, + sizeof(reqbuf) - reqbytes, + &numbytes)) { + if (numbytes > 0) + fwrite(reqbuf + reqbytes, 1, numbytes, stdout); + reqbytes += numbytes; + } + } while (reqbytes < sizeof(reqterm) + || memcmp(reqbuf + reqbytes - sizeof(reqterm), reqterm, + sizeof(reqterm)) != 0); + + if ((streamid & QUIC_STREAM_DIR_UNI) != 0) { + /* + * Incoming stream was uni-directional. Create a server initiated + * uni-directional stream for the response. + */ + if (!ossl_quic_tserver_stream_new(qtserv, 1, &streamid)) { + BIO_printf(bio_err, "Failed creating response stream\n"); + goto end; + } } - } while (reqbytes < sizeof(reqterm) - || memcmp(reqbuf + reqbytes - sizeof(reqterm), reqterm, - sizeof(reqterm)) != 0); - - /* Send the response */ - ossl_quic_tserver_tick(qtserv); - if (!ossl_quic_tserver_write(qtserv, 0, (unsigned char *)msg, strlen(msg), - &numbytes)) - goto end; + /* Send the response */ - if (!ossl_quic_tserver_conclude(qtserv, 0)) - goto end; - - /* Wait until all data we have sent has been acked */ - while (!ossl_quic_tserver_is_terminated(qtserv) - && !ossl_quic_tserver_is_stream_totally_acked(qtserv, 0)) { ossl_quic_tserver_tick(qtserv); - wait_for_activity(qtserv); - } + if (!ossl_quic_tserver_write(qtserv, streamid, + (unsigned char *)response[respnum], + strlen(response[respnum]), &numbytes)) + goto end; - while (!ossl_quic_tserver_shutdown(qtserv)) - wait_for_activity(qtserv); - - /* Close down here */ + if (!ossl_quic_tserver_conclude(qtserv, streamid)) + goto end; + } - ret = EXIT_SUCCESS; end: /* Free twice because we did an up-ref */ BIO_free(bio); |