http3 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,347 @@
1
+ #include "nghttp3.h"
2
+ #include <stdarg.h>
3
+
4
+ const quic_ext_api *http3_quic_api;
5
+
6
+ VALUE rb_mNghttp3;
7
+ VALUE rb_cNghttp3Info;
8
+ VALUE rb_eNghttp3Error;
9
+
10
+ /* Error classes */
11
+ VALUE rb_eNghttp3InvalidArgumentError;
12
+ VALUE rb_eNghttp3InvalidStateError;
13
+ VALUE rb_eNghttp3WouldBlockError;
14
+ VALUE rb_eNghttp3StreamInUseError;
15
+ VALUE rb_eNghttp3MalformedHTTPHeaderError;
16
+ VALUE rb_eNghttp3MalformedHTTPMessagingError;
17
+ VALUE rb_eNghttp3QPACKFatalError;
18
+ VALUE rb_eNghttp3QPACKHeaderTooLargeError;
19
+ VALUE rb_eNghttp3StreamNotFoundError;
20
+ VALUE rb_eNghttp3ConnClosingError;
21
+ VALUE rb_eNghttp3StreamDataOverflowError;
22
+ VALUE rb_eNghttp3FatalError;
23
+ VALUE rb_eNghttp3NoMemError;
24
+ VALUE rb_eNghttp3CallbackFailureError;
25
+
26
+ /*
27
+ * call-seq:
28
+ * Nghttp3.library_version -> Nghttp3::Info
29
+ * Nghttp3.library_version(least_version) -> Nghttp3::Info or nil
30
+ *
31
+ * Returns version information about the nghttp3 library.
32
+ * If least_version is specified and the library version is less than
33
+ * that value, returns nil.
34
+ */
35
+ static VALUE rb_nghttp3_library_version(int argc, VALUE *argv, VALUE self) {
36
+ VALUE rb_least_version;
37
+ int least_version = 0;
38
+ const nghttp3_info *info;
39
+ VALUE info_obj;
40
+
41
+ rb_scan_args(argc, argv, "01", &rb_least_version);
42
+
43
+ if (!NIL_P(rb_least_version)) {
44
+ least_version = NUM2INT(rb_least_version);
45
+ }
46
+
47
+ info = nghttp3_version(least_version);
48
+
49
+ if (info == NULL) {
50
+ return Qnil;
51
+ }
52
+
53
+ info_obj = rb_obj_alloc(rb_cNghttp3Info);
54
+ rb_iv_set(info_obj, "@age", INT2NUM(info->age));
55
+ rb_iv_set(info_obj, "@version_num", INT2NUM(info->version_num));
56
+ rb_iv_set(info_obj, "@version_str", rb_str_new_cstr(info->version_str));
57
+
58
+ return info_obj;
59
+ }
60
+
61
+ /*
62
+ * Returns the age of the nghttp3 library.
63
+ */
64
+ static VALUE rb_nghttp3_info_age(VALUE self) { return rb_iv_get(self, "@age"); }
65
+
66
+ /*
67
+ * Returns the numerical version of the nghttp3 library.
68
+ */
69
+ static VALUE rb_nghttp3_info_version_num(VALUE self) {
70
+ return rb_iv_get(self, "@version_num");
71
+ }
72
+
73
+ /*
74
+ * Returns the version string of the nghttp3 library.
75
+ */
76
+ static VALUE rb_nghttp3_info_version_str(VALUE self) {
77
+ return rb_iv_get(self, "@version_str");
78
+ }
79
+
80
+ /*
81
+ * Returns the appropriate Ruby error class for the given nghttp3 error code.
82
+ */
83
+ VALUE nghttp3_rb_error_class_for_code(int error_code) {
84
+ switch (error_code) {
85
+ case NGHTTP3_ERR_INVALID_ARGUMENT:
86
+ return rb_eNghttp3InvalidArgumentError;
87
+ case NGHTTP3_ERR_INVALID_STATE:
88
+ return rb_eNghttp3InvalidStateError;
89
+ case NGHTTP3_ERR_WOULDBLOCK:
90
+ return rb_eNghttp3WouldBlockError;
91
+ case NGHTTP3_ERR_STREAM_IN_USE:
92
+ return rb_eNghttp3StreamInUseError;
93
+ case NGHTTP3_ERR_MALFORMED_HTTP_HEADER:
94
+ return rb_eNghttp3MalformedHTTPHeaderError;
95
+ case NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING:
96
+ return rb_eNghttp3MalformedHTTPMessagingError;
97
+ case NGHTTP3_ERR_QPACK_FATAL:
98
+ return rb_eNghttp3QPACKFatalError;
99
+ case NGHTTP3_ERR_QPACK_HEADER_TOO_LARGE:
100
+ return rb_eNghttp3QPACKHeaderTooLargeError;
101
+ case NGHTTP3_ERR_STREAM_NOT_FOUND:
102
+ return rb_eNghttp3StreamNotFoundError;
103
+ case NGHTTP3_ERR_CONN_CLOSING:
104
+ return rb_eNghttp3ConnClosingError;
105
+ case NGHTTP3_ERR_STREAM_DATA_OVERFLOW:
106
+ return rb_eNghttp3StreamDataOverflowError;
107
+ case NGHTTP3_ERR_NOMEM:
108
+ return rb_eNghttp3NoMemError;
109
+ case NGHTTP3_ERR_CALLBACK_FAILURE:
110
+ return rb_eNghttp3CallbackFailureError;
111
+ default:
112
+ if (nghttp3_err_is_fatal(error_code)) {
113
+ return rb_eNghttp3FatalError;
114
+ }
115
+ return rb_eNghttp3Error;
116
+ }
117
+ }
118
+
119
+ /*
120
+ * Raises an appropriate Ruby exception for the given nghttp3 error code.
121
+ */
122
+ void nghttp3_rb_raise(int error_code, const char *fmt, ...) {
123
+ VALUE error_class;
124
+ char buf[256];
125
+ va_list args;
126
+
127
+ error_class = nghttp3_rb_error_class_for_code(error_code);
128
+
129
+ if (fmt != NULL) {
130
+ va_start(args, fmt);
131
+ vsnprintf(buf, sizeof(buf), fmt, args);
132
+ va_end(args);
133
+ rb_raise(error_class, "%s: %s", buf, nghttp3_strerror(error_code));
134
+ } else {
135
+ rb_raise(error_class, "%s", nghttp3_strerror(error_code));
136
+ }
137
+ }
138
+
139
+ /*
140
+ * call-seq:
141
+ * Nghttp3.err_is_fatal?(error_code) -> true or false
142
+ *
143
+ * Returns true if the given error code represents a fatal error.
144
+ */
145
+ static VALUE rb_nghttp3_err_is_fatal(VALUE self, VALUE rb_error_code) {
146
+ int error_code = NUM2INT(rb_error_code);
147
+ return nghttp3_err_is_fatal(error_code) ? Qtrue : Qfalse;
148
+ }
149
+
150
+ /*
151
+ * call-seq:
152
+ * Nghttp3.strerror(error_code) -> String
153
+ *
154
+ * Returns a textual representation of the given error code.
155
+ */
156
+ static VALUE rb_nghttp3_strerror(VALUE self, VALUE rb_error_code) {
157
+ int error_code = NUM2INT(rb_error_code);
158
+ const char *str = nghttp3_strerror(error_code);
159
+ return rb_str_new_cstr(str);
160
+ }
161
+
162
+ /*
163
+ * The quic gem's C function table for ABI major version major. quic must be
164
+ * loaded. Raises LoadError naming the versions when the quic gem has no
165
+ * such table (too old, or an incompatible major version) or a smaller one
166
+ * than this extension was built against.
167
+ */
168
+ static const quic_ext_api *http3_load_quic_api(uint32_t major) {
169
+ quic_ext_get_api_fn get = (quic_ext_get_api_fn)rb_ext_resolve_symbol(
170
+ "quic/quic", "quic_ext_get_api");
171
+ const quic_ext_api *api = get != NULL ? get(major) : NULL;
172
+ if (api == NULL || api->size < sizeof(quic_ext_api)) {
173
+ VALUE quic = rb_const_get(rb_cObject, rb_intern("QUIC"));
174
+ VALUE version = rb_const_get(quic, rb_intern("VERSION"));
175
+ rb_raise(rb_eLoadError,
176
+ "http3 needs the quic gem's C function table for quic/ext.h "
177
+ "ABI major version %u (quic ~> 0.0.3), which quic %" PRIsVALUE
178
+ " does not provide",
179
+ (unsigned int)major, version);
180
+ }
181
+ return api;
182
+ }
183
+
184
+ /*
185
+ * call-seq:
186
+ * HTTP3::Testing.load_quic_api(major) -> true
187
+ *
188
+ * Looks the quic gem's table up again for the given ABI major version, as
189
+ * loading http3 does, and raises LoadError if there is none. Internal, for
190
+ * testing the version check.
191
+ */
192
+ static VALUE rb_http3_testing_load_quic_api(VALUE self, VALUE major) {
193
+ http3_load_quic_api(NUM2UINT(major));
194
+ return Qtrue;
195
+ }
196
+
197
+ RUBY_FUNC_EXPORTED void Init_http3(void) {
198
+ /* quic.so has to be loaded before its symbols can be resolved. */
199
+ rb_require("quic");
200
+ http3_quic_api = http3_load_quic_api(QUIC_EXT_ABI_MAJOR);
201
+
202
+ /* The nghttp3 bindings live in HTTP3::Nghttp3. HTTP3 is also opened in
203
+ * lib/http3.rb; both must stay modules. */
204
+ VALUE rb_mHTTP3 = rb_define_module("HTTP3");
205
+ VALUE rb_mHTTP3Testing = rb_define_module_under(rb_mHTTP3, "Testing");
206
+ rb_define_singleton_method(rb_mHTTP3Testing, "load_quic_api",
207
+ rb_http3_testing_load_quic_api, 1);
208
+ rb_mNghttp3 = rb_define_module_under(rb_mHTTP3, "Nghttp3");
209
+
210
+ /* Define compile-time version constants */
211
+ rb_define_const(rb_mNghttp3, "NGHTTP3_VERSION",
212
+ rb_str_new_cstr(NGHTTP3_VERSION));
213
+ rb_define_const(rb_mNghttp3, "NGHTTP3_VERSION_NUM",
214
+ INT2NUM(NGHTTP3_VERSION_NUM));
215
+ rb_define_const(rb_mNghttp3, "NGHTTP3_VERSION_AGE",
216
+ INT2NUM(NGHTTP3_VERSION_AGE));
217
+
218
+ /* Define module method for runtime version */
219
+ rb_define_singleton_method(rb_mNghttp3, "library_version",
220
+ rb_nghttp3_library_version, -1);
221
+
222
+ /* Define Info class */
223
+ rb_cNghttp3Info = rb_define_class_under(rb_mNghttp3, "Info", rb_cObject);
224
+ rb_undef_method(rb_singleton_class(rb_cNghttp3Info), "new");
225
+ rb_define_method(rb_cNghttp3Info, "age", rb_nghttp3_info_age, 0);
226
+ rb_define_method(rb_cNghttp3Info, "version_num", rb_nghttp3_info_version_num,
227
+ 0);
228
+ rb_define_method(rb_cNghttp3Info, "version_str", rb_nghttp3_info_version_str,
229
+ 0);
230
+
231
+ /* Define base error class */
232
+ rb_eNghttp3Error =
233
+ rb_define_class_under(rb_mNghttp3, "Error", rb_eStandardError);
234
+
235
+ /* Define error code constants */
236
+ rb_define_const(rb_mNghttp3, "NGHTTP3_ERR_INVALID_ARGUMENT",
237
+ INT2NUM(NGHTTP3_ERR_INVALID_ARGUMENT));
238
+ rb_define_const(rb_mNghttp3, "NGHTTP3_ERR_INVALID_STATE",
239
+ INT2NUM(NGHTTP3_ERR_INVALID_STATE));
240
+ rb_define_const(rb_mNghttp3, "NGHTTP3_ERR_WOULDBLOCK",
241
+ INT2NUM(NGHTTP3_ERR_WOULDBLOCK));
242
+ rb_define_const(rb_mNghttp3, "NGHTTP3_ERR_STREAM_IN_USE",
243
+ INT2NUM(NGHTTP3_ERR_STREAM_IN_USE));
244
+ rb_define_const(rb_mNghttp3, "NGHTTP3_ERR_MALFORMED_HTTP_HEADER",
245
+ INT2NUM(NGHTTP3_ERR_MALFORMED_HTTP_HEADER));
246
+ rb_define_const(rb_mNghttp3, "NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING",
247
+ INT2NUM(NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING));
248
+ rb_define_const(rb_mNghttp3, "NGHTTP3_ERR_QPACK_FATAL",
249
+ INT2NUM(NGHTTP3_ERR_QPACK_FATAL));
250
+ rb_define_const(rb_mNghttp3, "NGHTTP3_ERR_QPACK_HEADER_TOO_LARGE",
251
+ INT2NUM(NGHTTP3_ERR_QPACK_HEADER_TOO_LARGE));
252
+ rb_define_const(rb_mNghttp3, "NGHTTP3_ERR_STREAM_NOT_FOUND",
253
+ INT2NUM(NGHTTP3_ERR_STREAM_NOT_FOUND));
254
+ rb_define_const(rb_mNghttp3, "NGHTTP3_ERR_CONN_CLOSING",
255
+ INT2NUM(NGHTTP3_ERR_CONN_CLOSING));
256
+ rb_define_const(rb_mNghttp3, "NGHTTP3_ERR_STREAM_DATA_OVERFLOW",
257
+ INT2NUM(NGHTTP3_ERR_STREAM_DATA_OVERFLOW));
258
+ rb_define_const(rb_mNghttp3, "NGHTTP3_ERR_FATAL", INT2NUM(NGHTTP3_ERR_FATAL));
259
+ rb_define_const(rb_mNghttp3, "NGHTTP3_ERR_NOMEM", INT2NUM(NGHTTP3_ERR_NOMEM));
260
+ rb_define_const(rb_mNghttp3, "NGHTTP3_ERR_CALLBACK_FAILURE",
261
+ INT2NUM(NGHTTP3_ERR_CALLBACK_FAILURE));
262
+
263
+ /* Define HTTP/3 application error code constants */
264
+ rb_define_const(rb_mNghttp3, "H3_NO_ERROR", INT2NUM(NGHTTP3_H3_NO_ERROR));
265
+ rb_define_const(rb_mNghttp3, "H3_GENERAL_PROTOCOL_ERROR",
266
+ INT2NUM(NGHTTP3_H3_GENERAL_PROTOCOL_ERROR));
267
+ rb_define_const(rb_mNghttp3, "H3_INTERNAL_ERROR",
268
+ INT2NUM(NGHTTP3_H3_INTERNAL_ERROR));
269
+ rb_define_const(rb_mNghttp3, "H3_STREAM_CREATION_ERROR",
270
+ INT2NUM(NGHTTP3_H3_STREAM_CREATION_ERROR));
271
+ rb_define_const(rb_mNghttp3, "H3_CLOSED_CRITICAL_STREAM",
272
+ INT2NUM(NGHTTP3_H3_CLOSED_CRITICAL_STREAM));
273
+ rb_define_const(rb_mNghttp3, "H3_FRAME_UNEXPECTED",
274
+ INT2NUM(NGHTTP3_H3_FRAME_UNEXPECTED));
275
+ rb_define_const(rb_mNghttp3, "H3_FRAME_ERROR",
276
+ INT2NUM(NGHTTP3_H3_FRAME_ERROR));
277
+ rb_define_const(rb_mNghttp3, "H3_EXCESSIVE_LOAD",
278
+ INT2NUM(NGHTTP3_H3_EXCESSIVE_LOAD));
279
+ rb_define_const(rb_mNghttp3, "H3_ID_ERROR", INT2NUM(NGHTTP3_H3_ID_ERROR));
280
+ rb_define_const(rb_mNghttp3, "H3_SETTINGS_ERROR",
281
+ INT2NUM(NGHTTP3_H3_SETTINGS_ERROR));
282
+ rb_define_const(rb_mNghttp3, "H3_MISSING_SETTINGS",
283
+ INT2NUM(NGHTTP3_H3_MISSING_SETTINGS));
284
+ rb_define_const(rb_mNghttp3, "H3_REQUEST_REJECTED",
285
+ INT2NUM(NGHTTP3_H3_REQUEST_REJECTED));
286
+ rb_define_const(rb_mNghttp3, "H3_REQUEST_CANCELLED",
287
+ INT2NUM(NGHTTP3_H3_REQUEST_CANCELLED));
288
+ rb_define_const(rb_mNghttp3, "H3_REQUEST_INCOMPLETE",
289
+ INT2NUM(NGHTTP3_H3_REQUEST_INCOMPLETE));
290
+ rb_define_const(rb_mNghttp3, "H3_MESSAGE_ERROR",
291
+ INT2NUM(NGHTTP3_H3_MESSAGE_ERROR));
292
+ rb_define_const(rb_mNghttp3, "H3_CONNECT_ERROR",
293
+ INT2NUM(NGHTTP3_H3_CONNECT_ERROR));
294
+ rb_define_const(rb_mNghttp3, "H3_VERSION_FALLBACK",
295
+ INT2NUM(NGHTTP3_H3_VERSION_FALLBACK));
296
+
297
+ /* Define data flag constants */
298
+ rb_define_const(rb_mNghttp3, "DATA_FLAG_NONE",
299
+ UINT2NUM(NGHTTP3_DATA_FLAG_NONE));
300
+ rb_define_const(rb_mNghttp3, "DATA_FLAG_EOF",
301
+ UINT2NUM(NGHTTP3_DATA_FLAG_EOF));
302
+ rb_define_const(rb_mNghttp3, "DATA_FLAG_NO_END_STREAM",
303
+ UINT2NUM(NGHTTP3_DATA_FLAG_NO_END_STREAM));
304
+
305
+ /* Define specific error classes */
306
+ rb_eNghttp3InvalidArgumentError = rb_define_class_under(
307
+ rb_mNghttp3, "InvalidArgumentError", rb_eNghttp3Error);
308
+ rb_eNghttp3InvalidStateError =
309
+ rb_define_class_under(rb_mNghttp3, "InvalidStateError", rb_eNghttp3Error);
310
+ rb_eNghttp3WouldBlockError =
311
+ rb_define_class_under(rb_mNghttp3, "WouldBlockError", rb_eNghttp3Error);
312
+ rb_eNghttp3StreamInUseError =
313
+ rb_define_class_under(rb_mNghttp3, "StreamInUseError", rb_eNghttp3Error);
314
+ rb_eNghttp3MalformedHTTPHeaderError = rb_define_class_under(
315
+ rb_mNghttp3, "MalformedHTTPHeaderError", rb_eNghttp3Error);
316
+ rb_eNghttp3MalformedHTTPMessagingError = rb_define_class_under(
317
+ rb_mNghttp3, "MalformedHTTPMessagingError", rb_eNghttp3Error);
318
+ rb_eNghttp3QPACKFatalError =
319
+ rb_define_class_under(rb_mNghttp3, "QPACKFatalError", rb_eNghttp3Error);
320
+ rb_eNghttp3QPACKHeaderTooLargeError = rb_define_class_under(
321
+ rb_mNghttp3, "QPACKHeaderTooLargeError", rb_eNghttp3Error);
322
+ rb_eNghttp3StreamNotFoundError = rb_define_class_under(
323
+ rb_mNghttp3, "StreamNotFoundError", rb_eNghttp3Error);
324
+ rb_eNghttp3ConnClosingError =
325
+ rb_define_class_under(rb_mNghttp3, "ConnClosingError", rb_eNghttp3Error);
326
+ rb_eNghttp3StreamDataOverflowError = rb_define_class_under(
327
+ rb_mNghttp3, "StreamDataOverflowError", rb_eNghttp3Error);
328
+ rb_eNghttp3FatalError =
329
+ rb_define_class_under(rb_mNghttp3, "FatalError", rb_eNghttp3Error);
330
+ rb_eNghttp3NoMemError =
331
+ rb_define_class_under(rb_mNghttp3, "NoMemError", rb_eNghttp3Error);
332
+ rb_eNghttp3CallbackFailureError = rb_define_class_under(
333
+ rb_mNghttp3, "CallbackFailureError", rb_eNghttp3Error);
334
+
335
+ /* Define error utility methods */
336
+ rb_define_singleton_method(rb_mNghttp3, "err_is_fatal?",
337
+ rb_nghttp3_err_is_fatal, 1);
338
+ rb_define_singleton_method(rb_mNghttp3, "strerror", rb_nghttp3_strerror, 1);
339
+
340
+ /* Initialize other classes */
341
+ Init_nghttp3_settings();
342
+ Init_nghttp3_nv();
343
+ Init_nghttp3_callbacks();
344
+ Init_nghttp3_connection();
345
+ Init_nghttp3_qpack();
346
+ Init_http3_session(rb_mHTTP3);
347
+ }
@@ -0,0 +1,105 @@
1
+ #ifndef NGHTTP3_RUBY_H
2
+ #define NGHTTP3_RUBY_H 1
3
+
4
+ #include "ruby.h"
5
+ #include "ruby/st.h"
6
+ #include <nghttp3/nghttp3.h>
7
+ #include <quic/ext.h>
8
+
9
+ /* The quic gem's C function table, looked up once by Init_http3. */
10
+ extern const quic_ext_api *http3_quic_api;
11
+
12
+ extern VALUE rb_mNghttp3;
13
+ extern VALUE rb_cNghttp3Info;
14
+ extern VALUE rb_eNghttp3Error;
15
+
16
+ /* Error classes */
17
+ extern VALUE rb_eNghttp3InvalidArgumentError;
18
+ extern VALUE rb_eNghttp3InvalidStateError;
19
+ extern VALUE rb_eNghttp3WouldBlockError;
20
+ extern VALUE rb_eNghttp3StreamInUseError;
21
+ extern VALUE rb_eNghttp3MalformedHTTPHeaderError;
22
+ extern VALUE rb_eNghttp3MalformedHTTPMessagingError;
23
+ extern VALUE rb_eNghttp3QPACKFatalError;
24
+ extern VALUE rb_eNghttp3QPACKHeaderTooLargeError;
25
+ extern VALUE rb_eNghttp3StreamNotFoundError;
26
+ extern VALUE rb_eNghttp3ConnClosingError;
27
+ extern VALUE rb_eNghttp3StreamDataOverflowError;
28
+ extern VALUE rb_eNghttp3FatalError;
29
+ extern VALUE rb_eNghttp3NoMemError;
30
+ extern VALUE rb_eNghttp3CallbackFailureError;
31
+
32
+ /* Data structure classes */
33
+ extern VALUE rb_cNghttp3Settings;
34
+ extern VALUE rb_cNghttp3NV;
35
+ extern VALUE rb_cNghttp3Connection;
36
+ extern VALUE rb_cNghttp3Callbacks;
37
+
38
+ /* QPACK module and classes */
39
+ extern VALUE rb_mNghttp3QPACK;
40
+ extern VALUE rb_cNghttp3QPACKEncoder;
41
+ extern VALUE rb_cNghttp3QPACKDecoder;
42
+
43
+ /* TypedData type for Settings (used by Connection) */
44
+ extern const rb_data_type_t settings_data_type;
45
+
46
+ /* TypedData type for Callbacks */
47
+ extern const rb_data_type_t callbacks_data_type;
48
+
49
+ /* The C side of an Nghttp3::Connection. nghttp3 gets a pointer to this
50
+ * struct as conn_user_data, never the Ruby object: GC.compact may move the
51
+ * object, and dcompact keeps self pointing at it. */
52
+ typedef struct {
53
+ nghttp3_conn *conn;
54
+ VALUE self;
55
+ VALUE settings; /* Prevent Settings from being GC'd */
56
+ VALUE callbacks; /* An Nghttp3::Callbacks, or nil */
57
+ VALUE stream_data_readers; /* stream_id => Proc/String for body data */
58
+ VALUE stream_user_data; /* stream_id => arbitrary user data */
59
+ /* stream_id => PendingStream *: the body Strings handed to nghttp3 and
60
+ * not yet wholly acknowledged, which nghttp3 may still read. dmark pins
61
+ * every one of them, so that GC.compact cannot move their bytes. */
62
+ st_table *pending;
63
+ /* An exception a Ruby callback raised inside nghttp3, kept here instead
64
+ * of unwinding through nghttp3's frames; the method that called into
65
+ * nghttp3 raises it once nghttp3 has returned. Qnil when there is none. */
66
+ VALUE pending_exc;
67
+ int is_closed;
68
+ int is_server;
69
+ } ConnectionObj;
70
+
71
+ /* Run body(arg) under rb_protect on behalf of a callback of obj. An
72
+ * exception is kept in obj->pending_exc (the first one wins) and turned
73
+ * into NGHTTP3_ERR_CALLBACK_FAILURE; 0 otherwise. */
74
+ int nghttp3_rb_protect(ConnectionObj *obj, VALUE (*body)(VALUE), VALUE arg);
75
+
76
+ /* Bookkeeping of the body Strings, for the acked_stream_data and
77
+ * stream_close callbacks. Both touch Ruby objects, so call them under
78
+ * nghttp3_rb_protect. */
79
+ void nghttp3_rb_conn_acked(ConnectionObj *obj, int64_t stream_id,
80
+ uint64_t datalen);
81
+ void nghttp3_rb_conn_stream_closed(ConnectionObj *obj, int64_t stream_id);
82
+
83
+ /* Helper functions */
84
+ VALUE nghttp3_rb_error_class_for_code(int error_code);
85
+ void nghttp3_rb_raise(int error_code, const char *fmt, ...);
86
+
87
+ /* Settings helper */
88
+ nghttp3_settings *nghttp3_rb_get_settings(VALUE rb_settings);
89
+
90
+ /* NV helper */
91
+ nghttp3_nv nghttp3_rb_nv_to_c(VALUE rb_nv);
92
+
93
+ /* Callbacks helper: install the C callbacks, which do their own
94
+ * bookkeeping and then call the Ruby blocks of conn's Callbacks, if any. */
95
+ void nghttp3_rb_setup_callbacks(nghttp3_callbacks *callbacks);
96
+
97
+ /* Init functions */
98
+ void Init_nghttp3_settings(void);
99
+ void Init_nghttp3_nv(void);
100
+ void Init_nghttp3_connection(void);
101
+ void Init_nghttp3_callbacks(void);
102
+ void Init_nghttp3_qpack(void);
103
+ void Init_http3_session(VALUE rb_mHTTP3);
104
+
105
+ #endif /* NGHTTP3_RUBY_H */