2 * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
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
9 #include "ossl-nghttp3.h"
10 #include <openssl/err.h>
14 static void make_nv(nghttp3_nv
*nv
, const char *name
, const char *value
)
16 nv
->name
= (uint8_t *)name
;
17 nv
->value
= (uint8_t *)value
;
18 nv
->namelen
= strlen(name
);
19 nv
->valuelen
= strlen(value
);
20 nv
->flags
= NGHTTP3_NV_FLAG_NONE
;
23 static int on_recv_header(nghttp3_conn
*h3conn
, int64_t stream_id
,
25 nghttp3_rcbuf
*name
, nghttp3_rcbuf
*value
,
28 void *stream_user_data
)
30 nghttp3_vec vname
, vvalue
;
32 /* Received a single HTTP header. */
33 vname
= nghttp3_rcbuf_get_buf(name
);
34 vvalue
= nghttp3_rcbuf_get_buf(value
);
36 fwrite(vname
.base
, vname
.len
, 1, stderr
);
37 fprintf(stderr
, ": ");
38 fwrite(vvalue
.base
, vvalue
.len
, 1, stderr
);
39 fprintf(stderr
, "\n");
44 static int on_end_headers(nghttp3_conn
*h3conn
, int64_t stream_id
,
46 void *conn_user_data
, void *stream_user_data
)
48 fprintf(stderr
, "\n");
52 static int on_recv_data(nghttp3_conn
*h3conn
, int64_t stream_id
,
53 const uint8_t *data
, size_t datalen
,
54 void *conn_user_data
, void *stream_user_data
)
58 /* HTTP response body data - write it to stdout. */
60 wr
= fwrite(data
, 1, datalen
, stdout
);
71 static int on_end_stream(nghttp3_conn
*h3conn
, int64_t stream_id
,
72 void *conn_user_data
, void *stream_user_data
)
74 /* HTTP transaction is done - set done flag so that we stop looping. */
79 int main(int argc
, char **argv
)
83 OSSL_DEMO_H3_CONN
*conn
= NULL
;
85 nghttp3_callbacks callbacks
= {0};
89 /* Check arguments. */
91 fprintf(stderr
, "usage: %s <host:port>\n", argv
[0]);
98 if ((ctx
= SSL_CTX_new(OSSL_QUIC_client_method())) == NULL
)
101 SSL_CTX_set_verify(ctx
, SSL_VERIFY_PEER
, NULL
);
103 if (SSL_CTX_set_default_verify_paths(ctx
) == 0)
106 /* Setup callbacks. */
107 callbacks
.recv_header
= on_recv_header
;
108 callbacks
.end_headers
= on_end_headers
;
109 callbacks
.recv_data
= on_recv_data
;
110 callbacks
.end_stream
= on_end_stream
;
112 /* Create connection. */
113 if ((conn
= OSSL_DEMO_H3_CONN_new_for_addr(ctx
, addr
, &callbacks
,
114 NULL
, NULL
)) == NULL
) {
115 ERR_raise_data(ERR_LIB_USER
, ERR_R_OPERATION_FAIL
,
116 "cannot create HTTP/3 connection");
120 /* Build HTTP headers. */
121 make_nv(&nva
[num_nv
++], ":method", "GET");
122 make_nv(&nva
[num_nv
++], ":scheme", "https");
123 make_nv(&nva
[num_nv
++], ":authority", addr
);
124 make_nv(&nva
[num_nv
++], ":path", "/");
125 make_nv(&nva
[num_nv
++], "user-agent", "OpenSSL-Demo/nghttp3");
127 /* Submit request. */
128 if (!OSSL_DEMO_H3_CONN_submit_request(conn
, nva
, num_nv
, NULL
, NULL
)) {
129 ERR_raise_data(ERR_LIB_USER
, ERR_R_OPERATION_FAIL
,
130 "cannot submit HTTP/3 request");
134 /* Wait for request to complete. */
136 if (!OSSL_DEMO_H3_CONN_handle_events(conn
)) {
137 ERR_raise_data(ERR_LIB_USER
, ERR_R_OPERATION_FAIL
,
138 "cannot handle events");
145 ERR_print_errors_fp(stderr
);
147 OSSL_DEMO_H3_CONN_free(conn
);