123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- /*
- * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the Apache License 2.0 (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
- #include "ossl-nghttp3.h"
- #include <openssl/err.h>
- static int done;
- static void make_nv(nghttp3_nv *nv, const char *name, const char *value)
- {
- nv->name = (uint8_t *)name;
- nv->value = (uint8_t *)value;
- nv->namelen = strlen(name);
- nv->valuelen = strlen(value);
- nv->flags = NGHTTP3_NV_FLAG_NONE;
- }
- static int on_recv_header(nghttp3_conn *h3conn, int64_t stream_id,
- int32_t token,
- nghttp3_rcbuf *name, nghttp3_rcbuf *value,
- uint8_t flags,
- void *conn_user_data,
- void *stream_user_data)
- {
- nghttp3_vec vname, vvalue;
- /* Received a single HTTP header. */
- vname = nghttp3_rcbuf_get_buf(name);
- vvalue = nghttp3_rcbuf_get_buf(value);
- fwrite(vname.base, vname.len, 1, stderr);
- fprintf(stderr, ": ");
- fwrite(vvalue.base, vvalue.len, 1, stderr);
- fprintf(stderr, "\n");
- return 0;
- }
- static int on_end_headers(nghttp3_conn *h3conn, int64_t stream_id,
- int fin,
- void *conn_user_data, void *stream_user_data)
- {
- fprintf(stderr, "\n");
- return 0;
- }
- static int on_recv_data(nghttp3_conn *h3conn, int64_t stream_id,
- const uint8_t *data, size_t datalen,
- void *conn_user_data, void *stream_user_data)
- {
- ssize_t wr;
- /* HTTP response body data - write it to stdout. */
- while (datalen > 0) {
- wr = fwrite(data, 1, datalen, stdout);
- if (wr < 0)
- return 1;
- data += wr;
- datalen -= wr;
- }
- return 0;
- }
- static int on_end_stream(nghttp3_conn *h3conn, int64_t stream_id,
- void *conn_user_data, void *stream_user_data)
- {
- /* HTTP transaction is done - set done flag so that we stop looping. */
- done = 1;
- return 0;
- }
- int main(int argc, char **argv)
- {
- int ret = 1;
- SSL_CTX *ctx = NULL;
- OSSL_DEMO_H3_CONN *conn = NULL;
- nghttp3_nv nva[16];
- nghttp3_callbacks callbacks = {0};
- size_t num_nv = 0;
- const char *addr;
- /* Check arguments. */
- if (argc < 2) {
- fprintf(stderr, "usage: %s <host:port>\n", argv[0]);
- goto err;
- }
- addr = argv[1];
- /* Setup SSL_CTX. */
- if ((ctx = SSL_CTX_new(OSSL_QUIC_client_method())) == NULL)
- goto err;
- SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
- if (SSL_CTX_set_default_verify_paths(ctx) == 0)
- goto err;
- /* Setup callbacks. */
- callbacks.recv_header = on_recv_header;
- callbacks.end_headers = on_end_headers;
- callbacks.recv_data = on_recv_data;
- callbacks.end_stream = on_end_stream;
- /* Create connection. */
- if ((conn = OSSL_DEMO_H3_CONN_new_for_addr(ctx, addr, &callbacks,
- NULL, NULL)) == NULL) {
- ERR_raise_data(ERR_LIB_USER, ERR_R_OPERATION_FAIL,
- "cannot create HTTP/3 connection");
- goto err;
- }
- /* Build HTTP headers. */
- make_nv(&nva[num_nv++], ":method", "GET");
- make_nv(&nva[num_nv++], ":scheme", "https");
- make_nv(&nva[num_nv++], ":authority", addr);
- make_nv(&nva[num_nv++], ":path", "/");
- make_nv(&nva[num_nv++], "user-agent", "OpenSSL-Demo/nghttp3");
- /* Submit request. */
- if (!OSSL_DEMO_H3_CONN_submit_request(conn, nva, num_nv, NULL, NULL)) {
- ERR_raise_data(ERR_LIB_USER, ERR_R_OPERATION_FAIL,
- "cannot submit HTTP/3 request");
- goto err;
- }
- /* Wait for request to complete. */
- while (!done)
- if (!OSSL_DEMO_H3_CONN_handle_events(conn)) {
- ERR_raise_data(ERR_LIB_USER, ERR_R_OPERATION_FAIL,
- "cannot handle events");
- goto err;
- }
- ret = 0;
- err:
- if (ret != 0)
- ERR_print_errors_fp(stderr);
- OSSL_DEMO_H3_CONN_free(conn);
- SSL_CTX_free(ctx);
- return ret;
- }
|