ossl-nghttp3-demo.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include "ossl-nghttp3.h"
  10. #include <openssl/err.h>
  11. static int done;
  12. static void make_nv(nghttp3_nv *nv, const char *name, const char *value)
  13. {
  14. nv->name = (uint8_t *)name;
  15. nv->value = (uint8_t *)value;
  16. nv->namelen = strlen(name);
  17. nv->valuelen = strlen(value);
  18. nv->flags = NGHTTP3_NV_FLAG_NONE;
  19. }
  20. static int on_recv_header(nghttp3_conn *h3conn, int64_t stream_id,
  21. int32_t token,
  22. nghttp3_rcbuf *name, nghttp3_rcbuf *value,
  23. uint8_t flags,
  24. void *conn_user_data,
  25. void *stream_user_data)
  26. {
  27. nghttp3_vec vname, vvalue;
  28. /* Received a single HTTP header. */
  29. vname = nghttp3_rcbuf_get_buf(name);
  30. vvalue = nghttp3_rcbuf_get_buf(value);
  31. fwrite(vname.base, vname.len, 1, stderr);
  32. fprintf(stderr, ": ");
  33. fwrite(vvalue.base, vvalue.len, 1, stderr);
  34. fprintf(stderr, "\n");
  35. return 0;
  36. }
  37. static int on_end_headers(nghttp3_conn *h3conn, int64_t stream_id,
  38. int fin,
  39. void *conn_user_data, void *stream_user_data)
  40. {
  41. fprintf(stderr, "\n");
  42. return 0;
  43. }
  44. static int on_recv_data(nghttp3_conn *h3conn, int64_t stream_id,
  45. const uint8_t *data, size_t datalen,
  46. void *conn_user_data, void *stream_user_data)
  47. {
  48. ssize_t wr;
  49. /* HTTP response body data - write it to stdout. */
  50. while (datalen > 0) {
  51. wr = fwrite(data, 1, datalen, stdout);
  52. if (wr < 0)
  53. return 1;
  54. data += wr;
  55. datalen -= wr;
  56. }
  57. return 0;
  58. }
  59. static int on_end_stream(nghttp3_conn *h3conn, int64_t stream_id,
  60. void *conn_user_data, void *stream_user_data)
  61. {
  62. /* HTTP transaction is done - set done flag so that we stop looping. */
  63. done = 1;
  64. return 0;
  65. }
  66. int main(int argc, char **argv)
  67. {
  68. int ret = 1;
  69. SSL_CTX *ctx = NULL;
  70. OSSL_DEMO_H3_CONN *conn = NULL;
  71. nghttp3_nv nva[16];
  72. nghttp3_callbacks callbacks = {0};
  73. size_t num_nv = 0;
  74. const char *addr;
  75. /* Check arguments. */
  76. if (argc < 2) {
  77. fprintf(stderr, "usage: %s <host:port>\n", argv[0]);
  78. goto err;
  79. }
  80. addr = argv[1];
  81. /* Setup SSL_CTX. */
  82. if ((ctx = SSL_CTX_new(OSSL_QUIC_client_method())) == NULL)
  83. goto err;
  84. SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
  85. if (SSL_CTX_set_default_verify_paths(ctx) == 0)
  86. goto err;
  87. /* Setup callbacks. */
  88. callbacks.recv_header = on_recv_header;
  89. callbacks.end_headers = on_end_headers;
  90. callbacks.recv_data = on_recv_data;
  91. callbacks.end_stream = on_end_stream;
  92. /* Create connection. */
  93. if ((conn = OSSL_DEMO_H3_CONN_new_for_addr(ctx, addr, &callbacks,
  94. NULL, NULL)) == NULL) {
  95. ERR_raise_data(ERR_LIB_USER, ERR_R_OPERATION_FAIL,
  96. "cannot create HTTP/3 connection");
  97. goto err;
  98. }
  99. /* Build HTTP headers. */
  100. make_nv(&nva[num_nv++], ":method", "GET");
  101. make_nv(&nva[num_nv++], ":scheme", "https");
  102. make_nv(&nva[num_nv++], ":authority", addr);
  103. make_nv(&nva[num_nv++], ":path", "/");
  104. make_nv(&nva[num_nv++], "user-agent", "OpenSSL-Demo/nghttp3");
  105. /* Submit request. */
  106. if (!OSSL_DEMO_H3_CONN_submit_request(conn, nva, num_nv, NULL, NULL)) {
  107. ERR_raise_data(ERR_LIB_USER, ERR_R_OPERATION_FAIL,
  108. "cannot submit HTTP/3 request");
  109. goto err;
  110. }
  111. /* Wait for request to complete. */
  112. while (!done)
  113. if (!OSSL_DEMO_H3_CONN_handle_events(conn)) {
  114. ERR_raise_data(ERR_LIB_USER, ERR_R_OPERATION_FAIL,
  115. "cannot handle events");
  116. goto err;
  117. }
  118. ret = 0;
  119. err:
  120. if (ret != 0)
  121. ERR_print_errors_fp(stderr);
  122. OSSL_DEMO_H3_CONN_free(conn);
  123. SSL_CTX_free(ctx);
  124. return ret;
  125. }