maph 1.0.0 High-Performance Memory-Mapped Key-Value Database with O(1) Lookups

Loading...
Searching...
No Matches
http3_client.c
Go to the documentation of this file.
1#ifdef LIBUS_USE_QUIC
2
3#define _GNU_SOURCE
4#include <unistd.h>
5#include <stdlib.h>
6
7/* Experimental HTTP/3 client */
8#include <libusockets.h>
9
10/* Quic interface is not exposed under libusockets.h yet */
11#include "quic.h"
12
13/* Let's just have this one here for now */
14us_quic_socket_context_t *context;
15 int responses = 0;
16
17#include <stdio.h>
18
19 unsigned long long requests = 0;
20
21 struct us_loop_t *loop;
22
23/* Loop callbacks not used in this example */
24 void on_wakeup(struct us_loop_t *loop) {}
25 void on_pre(struct us_loop_t *loop) {}
26 void on_post(struct us_loop_t *loop) {}
27
28 int per_socket_requests[100];
29us_quic_socket_t *sockets[100];
30 int num_sockets = 0;
31
32 void on_print(struct us_timer_t *t) {
33 printf("Responses per second: %d\n", responses);
34 responses = 0;
35
36 for (int i = 0; i < num_sockets; i++) {
37
38 if (per_socket_requests[i] == 0) {
39 printf("One socket had no responses, closing!\n");
40 exit(0);
41 }
42
43 printf("Responses per second for socket %d: %d\n", i, per_socket_requests[i]);
44 per_socket_requests[i] = 0;
45 }
46
47
48}
49
50 void print_current_headers() {
51 /* Iterate the headers and print them */
52 for (int i = 0, more = 1; more; i++) {
53 char *name, *value;
54 int name_length, value_length;
55 if (more = us_quic_socket_context_get_header(context, i, &name, &name_length, &value, &value_length)) {
56 printf("header %.*s = %.*s\n", name_length, name, value_length, value);
57 }
58 }
59}
60
61/* This would be a request */
62 void on_stream_headers(us_quic_stream_t *s) {
63
64 for (int i = 0; i < num_sockets; i++) {
65 if (sockets[i] == us_quic_stream_socket(s)) {
66 per_socket_requests[i]++;
67 break;
68 }
69 if (i == num_sockets - 1) {
70 printf("Got response from socket we do not even have open!\n");
71 exit(0);
72 }
73 }
74
75 //printf("Response from %p\n", us_quic_stream_socket(s));
76
77 responses++;
78 //if (responses == 10) {
79 //on_print(NULL);
80 //}
81
82 //printf("CLIENT GOT HTTP RESPONSE!\n");
83
84 //print_current_headers();
85
86 /* Make a new stream */
87 us_quic_socket_create_stream(us_quic_stream_socket(s));
88}
89
90/* And this would be the body of the request */
91 void on_stream_data(us_quic_stream_t *s, char *data, int length) {
92 //printf("Body length is: %d\n", length);
93
94 //printf("%.*s\n", length, data);
95}
96
97 void on_stream_writable(us_quic_stream_t *s) {
98
99}
100
101 void on_stream_close(us_quic_stream_t *s) {
102 //printf("Stream closed\n");
103}
104
105 int ignore = 0;
106
107 void on_start(struct us_timer_t *t) {
108
109
110
111 if (num_sockets < 10) {
112 us_quic_socket_t *connect_socket = us_quic_socket_context_connect(context, "::1", 9004);
113 } else {
114 if (!ignore) {
115
116 struct us_timer_t *delayTimer = us_create_timer(loop, 0, 0);
117 us_timer_set(delayTimer, on_print, 1000, 1000);
118
119 ignore = 1;
120 printf("Starting now\n");
121 for (int i = 0; i < num_sockets; i++) {
122 for (int j = 0; j < 32; j++) {
123 us_quic_socket_create_stream(sockets[i]);
124 }
125 }
126 }
127 }
128
129}
130
131/* On new connection */
132 void on_open(us_quic_socket_t *s, int is_client) {
133 printf("New QUIC connection! Is client: %d\n", is_client);
134
135 // for now the lib creates a stream by itself here if client
136 if (is_client) {
137 sockets[num_sockets++] = s;
138 } else {
139 printf("yololooo\n");
140 exit(0);
141 }
142}
143
144/* On new stream */
145 void on_stream_open(us_quic_stream_t *s, int is_client) {
146 //printf("Stream open is_client: %d!\n", is_client);
147
148 /* The client begins by making a request */
149 if (is_client) {
150 us_quic_socket_context_set_header(NULL, 0, ":method", 7, "GET", 3);
151 //us_quic_socket_context_set_header(NULL, 1, ":path", 5, "/hi", 3);
152
153 us_quic_socket_context_send_headers(NULL, s, 1, 0);
154 /* Shutdown writing (send FIN) */
155 us_quic_stream_shutdown(s);
156 }
157}
158
159 void on_close(us_quic_socket_t *s) {
160 printf("QUIC connection closed!\n");
161}
162
163 int main() {
164 /* Create the event loop */
165 loop = us_create_loop(0, on_wakeup, on_pre, on_post, 0);
166
167 /* SSL cert is always needed for quic */
168 us_quic_socket_context_options_t options = {
169 .cert_file_name = "",
170 .key_file_name = ""
171 };
172
173 /* Create quic socket context (assumes h3 for now) */
174 context = us_create_quic_socket_context(loop, options);
175
176 /* Specify application callbacks */
177 us_quic_socket_context_on_stream_data(context, on_stream_data);
178 us_quic_socket_context_on_stream_open(context, on_stream_open);
179 us_quic_socket_context_on_stream_close(context, on_stream_close);
180 us_quic_socket_context_on_stream_writable(context, on_stream_writable);
181 us_quic_socket_context_on_stream_headers(context, on_stream_headers);
182 us_quic_socket_context_on_open(context, on_open);
183 us_quic_socket_context_on_close(context, on_close);
184
185 struct us_timer_t *startTimer = us_create_timer(loop, 0, 0);
186 us_timer_set(startTimer, on_start, 100, 100);
187
188 /* We also establish a client connection that sends requests */
189 //for (int i = 0; i < 4; i++) {
190 //us_quic_socket_t *connect_socket = us_quic_socket_context_connect(context, "::1", 9004);
191 //}
192
193 /* Run the event loop */
194 us_loop_run(loop);
195
196 printf("Falling through!\n");
197}
198#else
199
200#include <stdio.h>
201
202 int main() {
203 printf("Compile with WITH_QUIC=1 make examples in order to build this example\n");
204}
205
206#endif
on_pre
void on_pre(struct us_loop_t *loop)
Definition echo_server.c:27
on_wakeup
void on_wakeup(struct us_loop_t *loop)
Definition echo_server.c:22
on_post
void on_post(struct us_loop_t *loop)
Definition echo_server.c:32
main
int main()
Definition http3_client.c:202
libusockets.h
us_create_timer
struct us_timer_t * us_create_timer(struct us_loop_t *loop, int fallthrough, unsigned int ext_size)
us_loop_run
void us_loop_run(struct us_loop_t *loop)
us_create_loop
struct us_loop_t * us_create_loop(void *hint, void(*wakeup_cb)(struct us_loop_t *loop), void(*pre_cb)(struct us_loop_t *loop), void(*post_cb)(struct us_loop_t *loop), unsigned int ext_size)
us_timer_set
void us_timer_set(struct us_timer_t *timer, void(*cb)(struct us_timer_t *t), int ms, int repeat_ms)
us_loop_t::data
struct us_internal_loop_data_t data
Definition asio.h:27
us_loop_t
Definition asio.h:26
quic.h