Coverage Report

Created: 2025-07-12 06:34

/src/h2o/include/h2o.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2014-2016 DeNA Co., Ltd., Kazuho Oku, Fastly, Inc.
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a copy
5
 * of this software and associated documentation files (the "Software"), to
6
 * deal in the Software without restriction, including without limitation the
7
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8
 * sell copies of the Software, and to permit persons to whom the Software is
9
 * furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20
 * IN THE SOFTWARE.
21
 */
22
#ifndef h2o_h
23
#define h2o_h
24
25
#ifdef __cplusplus
26
extern "C" {
27
#endif
28
29
#include <assert.h>
30
#include <stddef.h>
31
#include <stdint.h>
32
#include <string.h>
33
#include <stdlib.h>
34
#include <sys/time.h>
35
#include <sys/socket.h>
36
#include <time.h>
37
#include <unistd.h>
38
#include <openssl/ssl.h>
39
#include "h2o/filecache.h"
40
#include "h2o/header.h"
41
#include "h2o/hostinfo.h"
42
#include "h2o/memcached.h"
43
#include "h2o/redis.h"
44
#include "h2o/linklist.h"
45
#include "h2o/httpclient.h"
46
#include "h2o/memory.h"
47
#include "h2o/multithread.h"
48
#include "h2o/rand.h"
49
#include "h2o/socket.h"
50
#include "h2o/string_.h"
51
#include "h2o/time_.h"
52
#include "h2o/token.h"
53
#include "h2o/url.h"
54
#include "h2o/balancer.h"
55
#include "h2o/http2_common.h"
56
#include "h2o/send_state.h"
57
58
#ifndef H2O_USE_BROTLI
59
/* disabled for all but the standalone server, since the encoder is written in C++ */
60
#define H2O_USE_BROTLI 0
61
#endif
62
63
#ifndef H2O_MAX_HEADERS
64
37.5k
#define H2O_MAX_HEADERS 100
65
#endif
66
#ifndef H2O_MAX_REQLEN
67
20.1k
#define H2O_MAX_REQLEN (8192 + 4096 * (H2O_MAX_HEADERS))
68
#endif
69
70
#ifndef H2O_SOMAXCONN
71
/* simply use a large value, and let the kernel clip it to the internal max */
72
#define H2O_SOMAXCONN 65535
73
#endif
74
75
27.3k
#define H2O_HTTP2_MIN_STREAM_WINDOW_SIZE 65535
76
19.8k
#define H2O_HTTP2_MAX_STREAM_WINDOW_SIZE 16777216
77
78
1
#define H2O_DEFAULT_MAX_REQUEST_ENTITY_SIZE (1024 * 1024 * 1024)
79
1
#define H2O_DEFAULT_MAX_DELEGATIONS 5
80
1
#define H2O_DEFAULT_MAX_REPROCESSES 5
81
1
#define H2O_DEFAULT_HANDSHAKE_TIMEOUT_IN_SECS 10
82
1
#define H2O_DEFAULT_HANDSHAKE_TIMEOUT (H2O_DEFAULT_HANDSHAKE_TIMEOUT_IN_SECS * 1000)
83
1
#define H2O_DEFAULT_HTTP1_REQ_TIMEOUT_IN_SECS 10
84
1
#define H2O_DEFAULT_HTTP1_REQ_TIMEOUT (H2O_DEFAULT_HTTP1_REQ_TIMEOUT_IN_SECS * 1000)
85
1
#define H2O_DEFAULT_HTTP1_REQ_IO_TIMEOUT_IN_SECS 5
86
1
#define H2O_DEFAULT_HTTP1_REQ_IO_TIMEOUT (H2O_DEFAULT_HTTP1_REQ_IO_TIMEOUT_IN_SECS * 1000)
87
1
#define H2O_DEFAULT_HTTP1_UPGRADE_TO_HTTP2 1
88
1
#define H2O_DEFAULT_HTTP2_IDLE_TIMEOUT_IN_SECS 10
89
1
#define H2O_DEFAULT_HTTP2_IDLE_TIMEOUT (H2O_DEFAULT_HTTP2_IDLE_TIMEOUT_IN_SECS * 1000)
90
1
#define H2O_DEFAULT_HTTP2_GRACEFUL_SHUTDOWN_TIMEOUT_IN_SECS 0 /* no timeout */
91
1
#define H2O_DEFAULT_HTTP2_GRACEFUL_SHUTDOWN_TIMEOUT (H2O_DEFAULT_HTTP2_GRACEFUL_SHUTDOWN_TIMEOUT_IN_SECS * 1000)
92
2
#define H2O_DEFAULT_HTTP2_ACTIVE_STREAM_WINDOW_SIZE H2O_HTTP2_MAX_STREAM_WINDOW_SIZE
93
1
#define H2O_DEFAULT_HTTP3_ACTIVE_STREAM_WINDOW_SIZE H2O_DEFAULT_HTTP2_ACTIVE_STREAM_WINDOW_SIZE
94
3
#define H2O_DEFAULT_PROXY_IO_TIMEOUT_IN_SECS 30
95
3
#define H2O_DEFAULT_PROXY_IO_TIMEOUT (H2O_DEFAULT_PROXY_IO_TIMEOUT_IN_SECS * 1000)
96
#define H2O_DEFAULT_HAPPY_EYEBALLS_NAME_RESOLUTION_DELAY 50
97
#define H2O_DEFAULT_HAPPY_EYEBALLS_CONNECTION_ATTEMPT_DELAY 250
98
#define H2O_DEFAULT_PROXY_SSL_SESSION_CACHE_CAPACITY 4096
99
#define H2O_DEFAULT_PROXY_SSL_SESSION_CACHE_DURATION 86400000 /* 24 hours */
100
#define H2O_DEFAULT_PROXY_HTTP2_MAX_CONCURRENT_STREAMS 100
101
102
#define H2O_LOG_URI_PATH "/.well-known/h2olog"
103
104
typedef struct st_h2o_conn_t h2o_conn_t;
105
typedef struct st_h2o_context_t h2o_context_t;
106
typedef struct st_h2o_req_t h2o_req_t;
107
typedef struct st_h2o_ostream_t h2o_ostream_t;
108
typedef struct st_h2o_configurator_command_t h2o_configurator_command_t;
109
typedef struct st_h2o_configurator_t h2o_configurator_t;
110
typedef struct st_h2o_pathconf_t h2o_pathconf_t;
111
typedef struct st_h2o_hostconf_t h2o_hostconf_t;
112
typedef struct st_h2o_globalconf_t h2o_globalconf_t;
113
typedef struct st_h2o_mimemap_t h2o_mimemap_t;
114
typedef struct st_h2o_logconf_t h2o_logconf_t;
115
typedef struct st_h2o_headers_command_t h2o_headers_command_t;
116
117
/**
118
 * basic structure of a handler (an object that MAY generate a response)
119
 * The handlers should register themselves to h2o_context_t::handlers.
120
 */
121
typedef struct st_h2o_handler_t {
122
    size_t _config_slot;
123
    void (*on_context_init)(struct st_h2o_handler_t *self, h2o_context_t *ctx);
124
    void (*on_context_dispose)(struct st_h2o_handler_t *self, h2o_context_t *ctx);
125
    void (*dispose)(struct st_h2o_handler_t *self);
126
    int (*on_req)(struct st_h2o_handler_t *self, h2o_req_t *req);
127
    /**
128
     * If the flag is set, protocol handler may invoke the request handler before receiving the end of the request body. The request
129
     * handler can determine if the protocol handler has actually done so by checking if `req->proceed_req` is set to non-NULL.
130
     * In such case, the handler should replace `req->write_req.cb` (and ctx) with its own callback to receive the request body
131
     * bypassing the buffer of the protocol handler. Parts of the request body being received before the handler replacing the
132
     * callback is accessible via `req->entity`.
133
     * The request handler can delay replacing the callback to a later moment. In such case, the handler can determine if
134
     * `req->entity` already contains a complete request body by checking if `req->proceed_req` is NULL.
135
     */
136
    unsigned supports_request_streaming : 1;
137
    /**
138
     *
139
     */
140
    unsigned handles_expect : 1;
141
} h2o_handler_t;
142
143
/**
144
 * basic structure of a filter (an object that MAY modify a response)
145
 * The filters should register themselves to h2o_context_t::filters.
146
 */
147
typedef struct st_h2o_filter_t {
148
    size_t _config_slot;
149
    void (*on_context_init)(struct st_h2o_filter_t *self, h2o_context_t *ctx);
150
    void (*on_context_dispose)(struct st_h2o_filter_t *self, h2o_context_t *ctx);
151
    void (*dispose)(struct st_h2o_filter_t *self);
152
    void (*on_setup_ostream)(struct st_h2o_filter_t *self, h2o_req_t *req, h2o_ostream_t **slot);
153
    void (*on_informational)(struct st_h2o_filter_t *self, h2o_req_t *req);
154
} h2o_filter_t;
155
156
/**
157
 * basic structure of a logger (an object that MAY log a request)
158
 * The loggers should register themselves to h2o_context_t::loggers.
159
 */
160
typedef struct st_h2o_logger_t {
161
    size_t _config_slot;
162
    void (*on_context_init)(struct st_h2o_logger_t *self, h2o_context_t *ctx);
163
    void (*on_context_dispose)(struct st_h2o_logger_t *self, h2o_context_t *ctx);
164
    void (*dispose)(struct st_h2o_logger_t *self);
165
    void (*log_access)(struct st_h2o_logger_t *self, h2o_req_t *req);
166
} h2o_logger_t;
167
168
/**
169
 * contains stringified representations of a timestamp
170
 */
171
typedef struct st_h2o_timestamp_string_t {
172
    char rfc1123[H2O_TIMESTR_RFC1123_LEN + 1];
173
    char log[H2O_TIMESTR_LOG_LEN + 1];
174
} h2o_timestamp_string_t;
175
176
/**
177
 * a timestamp.
178
 * Applications should call h2o_get_timestamp to obtain a timestamp.
179
 */
180
typedef struct st_h2o_timestamp_t {
181
    struct timeval at;
182
    h2o_timestamp_string_t *str;
183
} h2o_timestamp_t;
184
185
typedef struct st_h2o_casper_conf_t {
186
    /**
187
     * capacity bits (0 to disable casper)
188
     */
189
    unsigned capacity_bits;
190
    /**
191
     * whether if all type of files should be tracked (or only the blocking assets)
192
     */
193
    int track_all_types;
194
} h2o_casper_conf_t;
195
196
typedef struct st_h2o_envconf_t {
197
    /**
198
     * parent
199
     */
200
    struct st_h2o_envconf_t *parent;
201
    /**
202
     * list of names to be unset
203
     */
204
    h2o_iovec_vector_t unsets;
205
    /**
206
     * list of name-value pairs to be set
207
     */
208
    h2o_iovec_vector_t sets;
209
} h2o_envconf_t;
210
211
struct st_h2o_pathconf_t {
212
    /**
213
     * globalconf to which the pathconf belongs
214
     */
215
    h2o_globalconf_t *global;
216
    /**
217
     * pathname in lower case, may or may not have "/" at last, NULL terminated, or is {NULL,0} if is fallback or extension-level
218
     */
219
    h2o_iovec_t path;
220
    /**
221
     * list of handlers
222
     */
223
    H2O_VECTOR(h2o_handler_t *) handlers;
224
    /**
225
     * list of filters to be applied unless when processing a subrequest.
226
     * The address of the list is set in `req->filters` and used when processing a request.
227
     */
228
    H2O_VECTOR(h2o_filter_t *) _filters;
229
    /**
230
     * list of loggers to be applied unless when processing a subrequest.
231
     * The address of the list is set in `req->loggers` and used when processing a request.
232
     */
233
    H2O_VECTOR(h2o_logger_t *) _loggers;
234
    /**
235
     * mimemap
236
     */
237
    h2o_mimemap_t *mimemap;
238
    /**
239
     * env
240
     */
241
    h2o_envconf_t *env;
242
    /**
243
     * error-log
244
     */
245
    struct {
246
        /**
247
         * if request-level errors should be emitted to stderr
248
         */
249
        unsigned emit_request_errors : 1;
250
    } error_log;
251
};
252
253
struct st_h2o_hostconf_t {
254
    /**
255
     * reverse reference to the global configuration
256
     */
257
    h2o_globalconf_t *global;
258
    /**
259
     * host and port
260
     */
261
    struct {
262
        /**
263
         * host and port (in lower-case; base is NULL-terminated)
264
         */
265
        h2o_iovec_t hostport;
266
        /**
267
         *  in lower-case; base is NULL-terminated
268
         */
269
        h2o_iovec_t host;
270
        /**
271
         * port number (or 65535 if default)
272
         */
273
        uint16_t port;
274
    } authority;
275
    /**
276
     * A boolean indicating that this hostconf can only be used for a request with the ":authority" pseudo-header field / "Host"
277
     * that matches hostport. When strict_match is false, then this hostconf is eligible for use as the fallback hostconf for a
278
     * request that does not match any applicable hostconf.
279
     */
280
    uint8_t strict_match;
281
    /**
282
     * list of path configurations
283
     */
284
    H2O_VECTOR(h2o_pathconf_t *) paths;
285
    /**
286
     * catch-all path configuration
287
     */
288
    h2o_pathconf_t fallback_path;
289
    /**
290
     * mimemap
291
     */
292
    h2o_mimemap_t *mimemap;
293
    /**
294
     * http2
295
     */
296
    struct {
297
        /**
298
         * whether if blocking assets being pulled should be given highest priority in case of clients that do not implement
299
         * dependency-based prioritization
300
         */
301
        unsigned reprioritize_blocking_assets : 1;
302
        /**
303
         * if server push should be used
304
         */
305
        unsigned push_preload : 1;
306
        /**
307
         * if cross origin pushes should be authorized
308
         */
309
        unsigned allow_cross_origin_push : 1;
310
        /**
311
         * casper settings
312
         */
313
        h2o_casper_conf_t casper;
314
    } http2;
315
};
316
317
typedef h2o_iovec_t (*final_status_handler_cb)(void *ctx, h2o_globalconf_t *gconf, h2o_req_t *req);
318
typedef const struct st_h2o_status_handler_t {
319
    h2o_iovec_t name;
320
    h2o_iovec_t (*final)(void *ctx, h2o_globalconf_t *gconf, h2o_req_t *req); /* mandatory, will be passed the optional context */
321
    void *(*init)(void); /* optional callback, allocates a context that will be passed to per_thread() */
322
    void (*per_thread)(void *priv, h2o_context_t *ctx); /* optional callback, will be called for each thread */
323
} h2o_status_handler_t;
324
325
typedef H2O_VECTOR(h2o_status_handler_t *) h2o_status_callbacks_t;
326
327
typedef enum h2o_send_informational_mode {
328
    H2O_SEND_INFORMATIONAL_MODE_EXCEPT_H1,
329
    H2O_SEND_INFORMATIONAL_MODE_NONE,
330
    H2O_SEND_INFORMATIONAL_MODE_ALL
331
} h2o_send_informational_mode_t;
332
333
/**
334
 * If zero copy should be used. "Always" indicates to the proxy handler that pipe-backed vectors should be used even when the http
335
 * protocol handler does not support zerocopy. This mode delays the load of content to userspace, at the cost of moving around
336
 * memory page between the socket connected to the origin and the pipe.
337
 */
338
typedef enum h2o_proxy_zerocopy_mode {
339
    H2O_PROXY_ZEROCOPY_DISABLED,
340
    H2O_PROXY_ZEROCOPY_ENABLED,
341
    H2O_PROXY_ZEROCOPY_ALWAYS
342
} h2o_proxy_zerocopy_mode_t;
343
344
typedef enum h2o_proxy_expect_mode {
345
    /**
346
     * Proxy doesn't handle anything related to Expect header or 100 continue responses.
347
     */
348
    H2O_PROXY_EXPECT_OFF,
349
    /**
350
     * Proxy adds its own expect header and suspend sending req body until it receives 100 response from the server.
351
     */
352
    H2O_PROXY_EXPECT_ON,
353
    /**
354
     * Proxy forwards expect req header to the server and 100 continue response to the client.
355
     * This also lets protocol handlers neither remove expect header from req headers nor
356
     * respond with 100 continue on its own, unlike when other values are set.
357
     */
358
    H2O_PROXY_EXPECT_FORWARD,
359
} h2o_proxy_expect_mode_t;
360
361
struct st_h2o_globalconf_t {
362
    /**
363
     * a NULL-terminated list of host contexts (h2o_hostconf_t)
364
     */
365
    h2o_hostconf_t **hosts;
366
    /**
367
     * The hostconf that will be used when none of the hostconfs for the listener match the request and they all have strict-match:
368
     * ON.
369
     */
370
    h2o_hostconf_t *fallback_host;
371
    /**
372
     * list of configurators
373
     */
374
    h2o_linklist_t configurators;
375
    /**
376
     * name of the server (not the hostname)
377
     */
378
    h2o_iovec_t server_name;
379
    /**
380
     * formated "sf-token" or "sf-string" for the proxy-status header
381
     */
382
    h2o_iovec_t proxy_status_identity;
383
    /**
384
     * maximum size of the accepted request entity (e.g. POST data)
385
     */
386
    size_t max_request_entity_size;
387
    /**
388
     * maximum count for delegations
389
     */
390
    unsigned max_delegations;
391
    /**
392
     * maximum count for reprocesses
393
     */
394
    unsigned max_reprocesses;
395
    /**
396
     * setuid user (or NULL)
397
     */
398
    char *user;
399
    /**
400
     * SSL handshake timeout
401
     */
402
    uint64_t handshake_timeout;
403
    /**
404
     * maximum number of pipes to retain for reuse
405
     */
406
    size_t max_spare_pipes;
407
408
    struct {
409
        /**
410
         * request timeout (in milliseconds)
411
         */
412
        uint64_t req_timeout;
413
        /**
414
         * request io timeout (in milliseconds)
415
         */
416
        uint64_t req_io_timeout;
417
        /**
418
         * a boolean value indicating whether or not to upgrade to HTTP/2
419
         */
420
        int upgrade_to_http2;
421
    } http1;
422
423
    struct {
424
        /**
425
         * idle timeout (in milliseconds)
426
         */
427
        uint64_t idle_timeout;
428
        /**
429
         * graceful shutdown timeout (in milliseconds)
430
         */
431
        uint64_t graceful_shutdown_timeout;
432
        /**
433
         * maximum number of HTTP2 streams to accept and advertise via HTTP2 SETTINGS.
434
         *
435
         * See max_concurrent_requests_per_connection and max_concurrent_streaming_requests_per_connection below for more info on
436
         * the actual number of requests that h2o is willing to process concurrently.
437
         */
438
        uint32_t max_streams;
439
        /**
440
         * maximum number of HTTP2 requests (per connection) to be handled simultaneously internally.
441
         * H2O accepts at most `max_streams` requests over HTTP/2, but internally limits the number of in-flight requests to the
442
         * value specified by this property in order to limit the resources allocated to a single connection.
443
         */
444
        size_t max_concurrent_requests_per_connection;
445
        /**
446
         * maximum number of HTTP2 streaming requests (per connection) to be handled simultaneously internally.
447
         */
448
        size_t max_concurrent_streaming_requests_per_connection;
449
        /**
450
         * maximum nuber of streams (per connection) to be allowed in IDLE / CLOSED state (used for tracking dependencies).
451
         */
452
        size_t max_streams_for_priority;
453
        /**
454
         * size of the stream-level flow control window (once it becomes active)
455
         */
456
        uint32_t active_stream_window_size;
457
        /**
458
         * conditions for latency optimization
459
         */
460
        h2o_socket_latency_optimization_conditions_t latency_optimization;
461
        /* */
462
        h2o_iovec_t origin_frame;
463
        /**
464
         * milliseconds to delay processing requests when suspicious behavior is detected
465
         */
466
        uint64_t dos_delay;
467
    } http2;
468
469
    struct {
470
        /**
471
         * idle timeout (in milliseconds)
472
         */
473
        uint64_t idle_timeout;
474
        /**
475
         * graceful shutdown timeout (in milliseconds)
476
         */
477
        uint64_t graceful_shutdown_timeout;
478
        /**
479
         * receive window size of the unblocked request stream
480
         */
481
        uint32_t active_stream_window_size;
482
        /**
483
         * See quicly_context_t::ack_frequency
484
         */
485
        uint16_t ack_frequency;
486
        /**
487
         * a boolean indicating if the delayed ack extension should be used (default true)
488
         */
489
        uint8_t allow_delayed_ack : 1;
490
        /**
491
         * a boolean indicating if UDP GSO should be used when possible
492
         */
493
        uint8_t use_gso : 1;
494
        /**
495
         * maximum number of HTTP3 streaming requests (per connection) to be handled simultaneously internally.
496
         */
497
        size_t max_concurrent_streaming_requests_per_connection;
498
    } http3;
499
500
    struct {
501
        /**
502
         * io timeout (in milliseconds)
503
         */
504
        uint64_t io_timeout;
505
        /**
506
         * io timeout (in milliseconds)
507
         */
508
        uint64_t connect_timeout;
509
        /**
510
         * io timeout (in milliseconds)
511
         */
512
        uint64_t first_byte_timeout;
513
        /**
514
         * keepalive timeout (in milliseconds)
515
         */
516
        uint64_t keepalive_timeout;
517
        /**
518
         * a boolean flag if set to true, instructs the proxy to preserve the x-forwarded-proto header passed by the client
519
         */
520
        unsigned preserve_x_forwarded_proto : 1;
521
        /**
522
         * a boolean flag if set to true, instructs the proxy to preserve the server header passed by the origin
523
         */
524
        unsigned preserve_server_header : 1;
525
        /**
526
         * a boolean flag if set to true, instructs the proxy to emit x-forwarded-proto and x-forwarded-for headers
527
         */
528
        unsigned emit_x_forwarded_headers : 1;
529
        /**
530
         * a boolean flag if set to true, instructs the proxy to emit a via header
531
         */
532
        unsigned emit_via_header : 1;
533
        /**
534
         * a boolean flag if set to true, instructs the proxy to emit a date header, if it's missing from the upstream response
535
         */
536
        unsigned emit_missing_date_header : 1;
537
        /**
538
         * maximum size to buffer for the response
539
         */
540
        size_t max_buffer_size;
541
        /**
542
         * a boolean flag if set to true, instructs to use zero copy (i.e., splice to pipe then splice to socket) if possible
543
         */
544
        h2o_proxy_zerocopy_mode_t zerocopy;
545
546
        struct {
547
            uint32_t max_concurrent_streams;
548
        } http2;
549
550
        /**
551
         * See the documentation of `h2o_httpclient_t::protocol_selector.ratio`.
552
         */
553
        struct {
554
            int8_t http2;
555
            int8_t http3;
556
        } protocol_ratio;
557
558
        /**
559
         * global socketpool
560
         */
561
        h2o_socketpool_t global_socketpool;
562
    } proxy;
563
564
    /**
565
     * enum indicating to what clients h2o sends 1xx response
566
     */
567
    h2o_send_informational_mode_t send_informational_mode;
568
569
    /**
570
     * mimemap
571
     */
572
    h2o_mimemap_t *mimemap;
573
574
    /**
575
     * filecache
576
     */
577
    struct {
578
        /* capacity of the filecache */
579
        size_t capacity;
580
    } filecache;
581
582
    /* status */
583
    h2o_status_callbacks_t statuses;
584
585
    size_t _num_config_slots;
586
};
587
588
enum {
589
    H2O_COMPRESS_HINT_AUTO = 0,    /* default: let h2o negociate compression based on the configuration */
590
    H2O_COMPRESS_HINT_DISABLE,     /* compression was explicitly disabled for this request */
591
    H2O_COMPRESS_HINT_ENABLE,      /* compression was explicitly enabled for this request */
592
    H2O_COMPRESS_HINT_ENABLE_GZIP, /* compression was explicitly enabled for this request, asking for gzip */
593
    H2O_COMPRESS_HINT_ENABLE_BR,   /* compression was explicitly enabled for this request, asking for br */
594
    H2O_COMPRESS_HINT_ENABLE_ZSTD, /* compression was explicitly enabled for this request, asking for zstd */
595
};
596
597
/**
598
 * holds various attributes related to the mime-type
599
 */
600
typedef struct st_h2o_mime_attributes_t {
601
    /**
602
     * whether if the content can be compressed by using gzip
603
     */
604
    char is_compressible;
605
    /**
606
     * how the resource should be prioritized
607
     */
608
    enum { H2O_MIME_ATTRIBUTE_PRIORITY_NORMAL = 0, H2O_MIME_ATTRIBUTE_PRIORITY_HIGHEST } priority;
609
} h2o_mime_attributes_t;
610
611
extern h2o_mime_attributes_t h2o_mime_attributes_as_is;
612
613
/**
614
 * represents either a mime-type (and associated info), or contains pathinfo in case of a dynamic type (e.g. .php files)
615
 */
616
typedef struct st_h2o_mimemap_type_t {
617
    enum { H2O_MIMEMAP_TYPE_MIMETYPE = 0, H2O_MIMEMAP_TYPE_DYNAMIC = 1 } type;
618
    union {
619
        struct {
620
            h2o_iovec_t mimetype;
621
            h2o_mime_attributes_t attr;
622
        };
623
        struct {
624
            h2o_pathconf_t pathconf;
625
        } dynamic;
626
    } data;
627
} h2o_mimemap_type_t;
628
629
enum {
630
    /* http1 protocol errors */
631
    H2O_STATUS_ERROR_400 = 0,
632
    H2O_STATUS_ERROR_401,
633
    H2O_STATUS_ERROR_403,
634
    H2O_STATUS_ERROR_404,
635
    H2O_STATUS_ERROR_405,
636
    H2O_STATUS_ERROR_413,
637
    H2O_STATUS_ERROR_416,
638
    H2O_STATUS_ERROR_417,
639
    H2O_STATUS_ERROR_421,
640
    H2O_STATUS_ERROR_500,
641
    H2O_STATUS_ERROR_502,
642
    H2O_STATUS_ERROR_503,
643
    H2O_STATUS_ERROR_MAX,
644
};
645
646
/**
647
 * holds various data related to the context
648
 */
649
typedef struct st_h2o_context_storage_item_t {
650
    void (*dispose)(void *data);
651
    void *data;
652
} h2o_context_storage_item_t;
653
654
typedef H2O_VECTOR(h2o_context_storage_item_t) h2o_context_storage_t;
655
656
typedef enum h2o_conn_state {
657
    H2O_CONN_STATE_IDLE,
658
    H2O_CONN_STATE_ACTIVE,
659
    H2O_CONN_STATE_SHUTDOWN,
660
} h2o_conn_state_t;
661
662
/**
663
 * context of the http server.
664
 */
665
struct st_h2o_context_t {
666
    /**
667
     * points to the loop (either uv_loop_t or h2o_evloop_t, depending on the value of H2O_USE_LIBUV)
668
     */
669
    h2o_loop_t *loop;
670
    /**
671
     * pointer to the global configuration
672
     */
673
    h2o_globalconf_t *globalconf;
674
    /**
675
     * queue for receiving messages from other contexts
676
     */
677
    h2o_multithread_queue_t *queue;
678
    /**
679
     * receivers
680
     */
681
    struct {
682
        h2o_multithread_receiver_t hostinfo_getaddr;
683
    } receivers;
684
    /**
685
     * open file cache
686
     */
687
    h2o_filecache_t *filecache;
688
    /**
689
     * the list of spare pipes currently retained for reuse
690
     */
691
    struct {
692
        int (*pipes)[2];
693
        size_t count;
694
    } spare_pipes;
695
    /**
696
     * context scope storage for general use
697
     */
698
    h2o_context_storage_t storage;
699
    /**
700
     * flag indicating if shutdown has been requested
701
     */
702
    int shutdown_requested;
703
    /**
704
     * connection states
705
     */
706
    struct {
707
        /**
708
         * link-list of h2o_conn_t
709
         *
710
         * list of connections in each state
711
         *
712
         * idle:
713
         *  - newly created connections are `idle`
714
         *  - `idle` connections become `active` as they receive requests
715
         *  - `active` connections become `idle` when there are no pending requests
716
         * active:
717
         *  - connections that contain pending requests
718
         * shutdown:
719
         *  - connections that are shutting down
720
         */
721
        h2o_linklist_t idle, active, shutdown;
722
        /**
723
         * number of connections in each state
724
         */
725
        union {
726
            /**
727
             * counters (the order MUST match that of h2o_connection_state_t; it is accessed by index via the use of counters[])
728
             */
729
            struct {
730
                size_t idle, active, shutdown;
731
            };
732
            size_t counters[1];
733
        } num_conns;
734
    } _conns;
735
    struct {
736
737
        struct {
738
            uint64_t request_timeouts;
739
            uint64_t request_io_timeouts;
740
        } events;
741
    } http1;
742
743
    struct {
744
        struct {
745
            /**
746
             * counter for http2 errors internally emitted by h2o
747
             */
748
            uint64_t protocol_level_errors[H2O_HTTP2_ERROR_MAX];
749
            /**
750
             * premature close on read
751
             */
752
            uint64_t read_closed;
753
            /**
754
             * premature close on write
755
             */
756
            uint64_t write_closed;
757
            /**
758
             * counter for http2 idle timeouts
759
             */
760
            uint64_t idle_timeouts;
761
            /**
762
             * streaming request counter
763
             */
764
            uint64_t streaming_requests;
765
        } events;
766
    } http2;
767
768
    struct {
769
        /**
770
         * thread-local variable shared by multiple instances of `h2o_quic_ctx_t::next_cid`
771
         */
772
        quicly_cid_plaintext_t next_cid;
773
        /**
774
         *
775
         */
776
        struct {
777
            /**
778
             * number of packets forwarded to another node in a cluster
779
             */
780
            uint64_t packet_forwarded;
781
            /**
782
             * number of forwarded packets received from another node in a cluster
783
             */
784
            uint64_t forwarded_packet_received;
785
        } events;
786
    } http3;
787
788
    struct {
789
        /**
790
         * the default client context for proxy
791
         */
792
        h2o_httpclient_ctx_t client_ctx;
793
        /**
794
         * the default connection pool for proxy
795
         */
796
        h2o_httpclient_connection_pool_t connpool;
797
    } proxy;
798
799
    struct {
800
        /**
801
         * counter for SSL errors
802
         */
803
        uint64_t errors;
804
        /**
805
         * counter for selected ALPN protocols
806
         */
807
        uint64_t alpn_h1;
808
        uint64_t alpn_h2;
809
        /**
810
         * counter for handshakes
811
         */
812
        uint64_t handshake_full;
813
        uint64_t handshake_resume;
814
        /**
815
         * summations of handshake latency in microsecond
816
         */
817
        uint64_t handshake_accum_time_full;
818
        uint64_t handshake_accum_time_resume;
819
    } ssl;
820
821
    /**
822
     * aggregated quic stats
823
     */
824
    h2o_quic_stats_t quic_stats;
825
826
    /**
827
     * connection stats
828
     */
829
    struct {
830
        uint64_t idle_closed;
831
    } connection_stats;
832
833
    /**
834
     * pointer to per-module configs
835
     */
836
    void **_module_configs;
837
838
    struct {
839
        struct timeval tv_at;
840
        h2o_timestamp_string_t *value;
841
    } _timestamp_cache;
842
843
    /**
844
     * counter for http1 error status internally emitted by h2o
845
     */
846
    uint64_t emitted_error_status[H2O_STATUS_ERROR_MAX];
847
848
    H2O_VECTOR(h2o_pathconf_t *) _pathconfs_inited;
849
};
850
851
/**
852
 * an object that generates a response.
853
 * The object is typically constructed by handlers calling the h2o_start_response function.
854
 */
855
typedef struct st_h2o_generator_t {
856
    /**
857
     * called by the core to request new data to be pushed via the h2o_send function.
858
     */
859
    void (*proceed)(struct st_h2o_generator_t *self, h2o_req_t *req);
860
    /**
861
     * called by the core when there is a need to terminate the response abruptly
862
     */
863
    void (*stop)(struct st_h2o_generator_t *self, h2o_req_t *req);
864
} h2o_generator_t;
865
866
/**
867
 * an output stream that may alter the output.
868
 * The object is typically constructed by filters calling the h2o_prepend_ostream function.
869
 */
870
struct st_h2o_ostream_t {
871
    /**
872
     * points to the next output stream
873
     */
874
    struct st_h2o_ostream_t *next;
875
    /**
876
     * Called by the core to send output.
877
     * Intermediary output streams should process the given output and call the h2o_ostream_send_next function either immediately or
878
     * at some time in the future.
879
     * Note: this callback is invoked only when progress can be made; For details, see `h2o_send`.
880
     */
881
    void (*do_send)(struct st_h2o_ostream_t *self, h2o_req_t *req, h2o_sendvec_t *bufs, size_t bufcnt, h2o_send_state_t state);
882
    /**
883
     * called by the core when there is a need to terminate the response abruptly
884
     */
885
    void (*stop)(struct st_h2o_ostream_t *self, h2o_req_t *req);
886
    /**
887
     * called by the core via h2o_send_informational
888
     */
889
    void (*send_informational)(struct st_h2o_ostream_t *self, h2o_req_t *req);
890
};
891
892
/**
893
 * a HTTP response
894
 */
895
typedef struct st_h2o_res_t {
896
    /**
897
     * status code
898
     */
899
    int status;
900
    /**
901
     * reason phrase
902
     */
903
    const char *reason;
904
    /**
905
     * length of the content (that is sent as the Content-Length header).
906
     * The default value is SIZE_MAX, which means that the length is indeterminate.
907
     * Generators should set this value whenever possible.
908
     */
909
    size_t content_length;
910
    /**
911
     * list of response headers
912
     */
913
    h2o_headers_t headers;
914
    /**
915
     * list of response trailers
916
     */
917
    h2o_headers_t trailers;
918
    /**
919
     * mime-related attributes (may be NULL)
920
     */
921
    h2o_mime_attributes_t *mime_attr;
922
    /**
923
     * retains the original response header before rewritten by ostream filters
924
     */
925
    struct {
926
        int status;
927
        h2o_headers_t headers;
928
    } original;
929
} h2o_res_t;
930
931
/**
932
 * debug state (currently only for HTTP/2)
933
 */
934
typedef struct st_h2o_http2_debug_state_t {
935
    h2o_iovec_vector_t json;
936
    ssize_t conn_flow_in;
937
    ssize_t conn_flow_out;
938
} h2o_http2_debug_state_t;
939
940
typedef struct st_h2o_conn_callbacks_t {
941
    /**
942
     * getsockname (return size of the obtained address, or 0 if failed)
943
     */
944
    socklen_t (*get_sockname)(h2o_conn_t *conn, struct sockaddr *sa);
945
    /**
946
     * getpeername (return size of the obtained address, or 0 if failed)
947
     */
948
    socklen_t (*get_peername)(h2o_conn_t *conn, struct sockaddr *sa);
949
    /**
950
     * returns picotls connection object used by the connection (or NULL if TLS is not used)
951
     */
952
    ptls_t *(*get_ptls)(h2o_conn_t *conn);
953
    /**
954
     * returns TLS SNI value being adopted (or NULL if SNI was not provided or adopted)
955
     */
956
    const char *(*get_ssl_server_name)(h2o_conn_t *conn);
957
    /**
958
     * returns trace state (see ptls_log for how it is being used)
959
     */
960
    ptls_log_conn_state_t *(*log_state)(h2o_conn_t *conn);
961
    /**
962
     * optional (i.e. may be NULL) callback for server push
963
     */
964
    void (*push_path)(h2o_req_t *req, const char *abspath, size_t abspath_len, int is_critical);
965
    /**
966
     * debug state callback (optional)
967
     */
968
    h2o_http2_debug_state_t *(*get_debug_state)(h2o_req_t *req, int hpack_enabled);
969
    /**
970
     * returns number of closed idle connections
971
     */
972
    void (*close_idle_connection)(h2o_conn_t *conn);
973
    /**
974
     * shutdown of connection is requested
975
     */
976
    void (*request_shutdown)(h2o_conn_t *conn);
977
    /**
978
     * for each request
979
     */
980
    int (*foreach_request)(h2o_conn_t *conn, int (*cb)(h2o_req_t *req, void *cbdata), void *cbdata);
981
    /**
982
     * returns number of requests inflight (optional, only supported by H2, H3)
983
     */
984
    uint32_t (*num_reqs_inflight)(h2o_conn_t *conn);
985
    /**
986
     * optional callbacks that return the tracer registry
987
     */
988
    quicly_tracer_t *(*get_tracer)(h2o_conn_t *conn);
989
    /**
990
     * An optional callback reporting an RTT estimate between the HTTP server and the HTTP client, measured in microseconds. At the
991
     * moment, this callback is available only for HTTP/2. For HTTP/2, time difference between when the SETTINGS frame was sent and
992
     * when a SETTINGS-ack was received is used as the estimate. The callback will return a negative value if the information is not
993
     * yet available.
994
     */
995
    int64_t (*get_rtt)(h2o_conn_t *conn);
996
    /**
997
     * optional callback that returns if zero copy is supported by the HTTP handler
998
     */
999
    int (*can_zerocopy)(h2o_conn_t *conn);
1000
    /**
1001
     * Mandatory callback that returns a number identifying the request of a particular connection (e.g., HTTP/2 stream ID)
1002
     */
1003
    uint64_t (*get_req_id)(h2o_req_t *req);
1004
    /**
1005
     * An optional callback to move the ownership of the socket to the caller. It returns non-null for cleartext connections
1006
     * and thus the caller can call h2o_socket_export() and write cleartext to its fd.
1007
     */
1008
    h2o_socket_t *(*steal_socket)(h2o_conn_t *conn);
1009
    /**
1010
     * logging callbacks (all of them are optional)
1011
     */
1012
    union {
1013
        struct {
1014
            h2o_iovec_t (*extensible_priorities)(h2o_req_t *req);
1015
            struct {
1016
                h2o_iovec_t (*cc_name)(h2o_req_t *req);
1017
                h2o_iovec_t (*delivery_rate)(h2o_req_t *req);
1018
            } transport;
1019
            struct {
1020
                h2o_iovec_t (*protocol_version)(h2o_req_t *req);
1021
                h2o_iovec_t (*session_reused)(h2o_req_t *req);
1022
                h2o_iovec_t (*cipher)(h2o_req_t *req);
1023
                h2o_iovec_t (*cipher_bits)(h2o_req_t *req);
1024
                h2o_iovec_t (*session_id)(h2o_req_t *req);
1025
                h2o_iovec_t (*negotiated_protocol)(h2o_req_t *req);
1026
                h2o_iovec_t (*ech_config_id)(h2o_req_t *req);
1027
                h2o_iovec_t (*ech_kem)(h2o_req_t *req);
1028
                h2o_iovec_t (*ech_cipher)(h2o_req_t *req);
1029
                h2o_iovec_t (*ech_cipher_bits)(h2o_req_t *req);
1030
                h2o_iovec_t (*backend)(h2o_req_t *req);
1031
            } ssl;
1032
            struct {
1033
                h2o_iovec_t (*request_index)(h2o_req_t *req);
1034
            } http1;
1035
            struct {
1036
                h2o_iovec_t (*stream_id)(h2o_req_t *req);
1037
                h2o_iovec_t (*priority_received)(h2o_req_t *req);
1038
                h2o_iovec_t (*priority_received_exclusive)(h2o_req_t *req);
1039
                h2o_iovec_t (*priority_received_parent)(h2o_req_t *req);
1040
                h2o_iovec_t (*priority_received_weight)(h2o_req_t *req);
1041
                h2o_iovec_t (*priority_actual)(h2o_req_t *req);
1042
                h2o_iovec_t (*priority_actual_parent)(h2o_req_t *req);
1043
                h2o_iovec_t (*priority_actual_weight)(h2o_req_t *req);
1044
            } http2;
1045
            struct {
1046
                h2o_iovec_t (*stream_id)(h2o_req_t *req);
1047
                h2o_iovec_t (*quic_stats)(h2o_req_t *req);
1048
                h2o_iovec_t (*quic_version)(h2o_req_t *req);
1049
            } http3;
1050
        };
1051
        h2o_iovec_t (*callbacks[1])(h2o_req_t *req);
1052
    } log_;
1053
} h2o_conn_callbacks_t;
1054
1055
/**
1056
 * basic structure of an HTTP connection (HTTP/1, HTTP/2, etc.)
1057
 */
1058
struct st_h2o_conn_t {
1059
    /**
1060
     * the context of the server
1061
     */
1062
    h2o_context_t *ctx;
1063
    /**
1064
     * NULL-terminated list of hostconfs bound to the connection
1065
     */
1066
    h2o_hostconf_t **hosts;
1067
    /**
1068
     * time when the connection was established
1069
     */
1070
    struct timeval connected_at;
1071
    /**
1072
     * connection id
1073
     */
1074
    uint64_t id;
1075
    /**
1076
     * callbacks
1077
     */
1078
    const h2o_conn_callbacks_t *callbacks;
1079
    /**
1080
     * connection UUID (UUIDv4 in the string representation).
1081
     */
1082
    struct {
1083
        char str[H2O_UUID_STR_RFC4122_LEN + 1];
1084
        uint8_t is_initialized;
1085
    } _uuid;
1086
    h2o_conn_state_t state;
1087
    /* internal structure */
1088
    h2o_linklist_t _conns;
1089
};
1090
1091
0
#define NOPAREN(...) __VA_ARGS__
1092
#define H2O_CONN_LIST_FOREACH(decl_var, conn_list, block)                                                                          \
1093
0
    do {                                                                                                                           \
1094
0
        h2o_linklist_t *_conn_list[] = NOPAREN conn_list;                                                                          \
1095
0
        size_t conn_list_len = PTLS_ELEMENTSOF(_conn_list);                                                                        \
1096
0
        h2o_linklist_t **_conn_list_iter = (_conn_list);                                                                           \
1097
0
        for (size_t i = 0; i < conn_list_len; i++) {                                                                               \
1098
0
            for (h2o_linklist_t *_node = _conn_list_iter[i]->next, *_node_next; _node != _conn_list_iter[i]; _node = _node_next) { \
1099
0
                _node_next = _node->next;                                                                                          \
1100
0
                h2o_conn_t *_h2o_conn = H2O_STRUCT_FROM_MEMBER(h2o_conn_t, _conns, _node);                                         \
1101
0
                decl_var = (void *)_h2o_conn;                                                                                      \
1102
0
                {                                                                                                                  \
1103
0
                    block                                                                                                          \
1104
0
                }                                                                                                                  \
1105
0
            }                                                                                                                      \
1106
0
        }                                                                                                                          \
1107
0
    } while (0)
1108
1109
/**
1110
 * filter used for capturing a response (can be used to implement subreq)
1111
 */
1112
typedef struct st_h2o_req_prefilter_t {
1113
    struct st_h2o_req_prefilter_t *next;
1114
    void (*on_setup_ostream)(struct st_h2o_req_prefilter_t *self, h2o_req_t *req, h2o_ostream_t **slot);
1115
} h2o_req_prefilter_t;
1116
1117
typedef struct st_h2o_req_overrides_t {
1118
    /**
1119
     * specific client context (or NULL)
1120
     */
1121
    h2o_httpclient_ctx_t *client_ctx;
1122
    /**
1123
     * connpool to be used when connecting to upstream (or NULL)
1124
     */
1125
    h2o_httpclient_connection_pool_t *connpool;
1126
    /**
1127
     * upstream to connect to (or NULL)
1128
     */
1129
    h2o_url_t *upstream;
1130
    /**
1131
     * parameters for rewriting the `Location` header (only used if match.len != 0)
1132
     */
1133
    struct {
1134
        /**
1135
         * if the prefix of the location header matches the url, then the header will be rewritten
1136
         */
1137
        h2o_url_t *match;
1138
        /**
1139
         * path prefix to be inserted upon rewrite
1140
         */
1141
        h2o_iovec_t path_prefix;
1142
    } location_rewrite;
1143
    /**
1144
     * whether the proxied request sends expect: 100-continue and wait 100 response before sending request body
1145
     */
1146
    h2o_proxy_expect_mode_t proxy_expect_mode;
1147
    /**
1148
     * whether if the PROXY header should be sent
1149
     */
1150
    unsigned use_proxy_protocol : 1;
1151
    /**
1152
     * whether the proxied request should preserve host
1153
     */
1154
    unsigned proxy_preserve_host : 1;
1155
    /**
1156
     * a boolean flag if set to true, instructs the proxy to close the frontend h1 connection on behalf of the upstream
1157
     */
1158
    unsigned forward_close_connection : 1;
1159
    /**
1160
     * headers rewrite commands to be used when sending requests to upstream (or NULL)
1161
     */
1162
    h2o_headers_command_t *headers_cmds;
1163
} h2o_req_overrides_t;
1164
1165
/**
1166
 * additional information for extension-based dynamic content
1167
 */
1168
typedef struct st_h2o_filereq_t {
1169
    h2o_iovec_t script_name;
1170
    h2o_iovec_t path_info;
1171
    h2o_iovec_t local_path;
1172
} h2o_filereq_t;
1173
1174
/**
1175
 * Called be the protocol handler to submit chunk of request body to the generator. The callback returns 0 if successful, otherwise
1176
 * a non-zero value. Once `write_req.cb` is called, subsequent invocations MUST be postponed until the `proceed_req` is called. At
1177
 * the moment, `write_req_cb` is required to create a copy of data being provided before returning. To avoid copying, we should
1178
 * consider delegating the responsibility of retaining the buffer to the caller.
1179
 */
1180
typedef int (*h2o_write_req_cb)(void *ctx, int is_end_stream);
1181
/**
1182
 * Called by the generator, in response to `h2o_write_req_cb` to indicate to the protocol handler that new chunk can be submitted,
1183
 * or to notify that an error has occurred. In the latter case, write might not be inflight. Note that `errstr` will be NULL (rather
1184
 * than an error code indicating EOS) when called in response to `h2o_write_req_cb` with `is_end_stream` set to 1.
1185
 */
1186
typedef void (*h2o_proceed_req_cb)(h2o_req_t *req, const char *errstr);
1187
/**
1188
 *
1189
 */
1190
typedef void (*h2o_forward_datagram_cb)(h2o_req_t *req, h2o_iovec_t *datagrams, size_t num_datagrams);
1191
1192
0
#define H2O_SEND_SERVER_TIMING_BASIC 1
1193
0
#define H2O_SEND_SERVER_TIMING_PROXY 2
1194
1195
/**
1196
 * a HTTP request
1197
 */
1198
struct st_h2o_req_t {
1199
    /**
1200
     * the underlying connection
1201
     */
1202
    h2o_conn_t *conn;
1203
    /**
1204
     * the request sent by the client (as is)
1205
     */
1206
    struct {
1207
        /**
1208
         * scheme (http, https, etc.)
1209
         */
1210
        const h2o_url_scheme_t *scheme;
1211
        /**
1212
         * authority (a.k.a. the Host header; the value is supplemented if missing before the handlers are being called)
1213
         */
1214
        h2o_iovec_t authority;
1215
        /**
1216
         * method
1217
         */
1218
        h2o_iovec_t method;
1219
        /**
1220
         * abs-path of the request (unmodified)
1221
         */
1222
        h2o_iovec_t path;
1223
        /**
1224
         * offset of '?' within path, or SIZE_MAX if not found
1225
         */
1226
        size_t query_at;
1227
    } input;
1228
    /**
1229
     * the host context
1230
     */
1231
    h2o_hostconf_t *hostconf;
1232
    /**
1233
     * the path context
1234
     */
1235
    h2o_pathconf_t *pathconf;
1236
    /**
1237
     * filters and the size of it
1238
     */
1239
    h2o_filter_t **filters;
1240
    size_t num_filters;
1241
    /**
1242
     * loggers and the size of it
1243
     */
1244
    h2o_logger_t **loggers;
1245
    size_t num_loggers;
1246
    /**
1247
     * the handler that has been executed
1248
     */
1249
    h2o_handler_t *handler;
1250
    /**
1251
     * scheme (http, https, etc.)
1252
     */
1253
    const h2o_url_scheme_t *scheme;
1254
    /**
1255
     * authority (of the processing request)
1256
     */
1257
    h2o_iovec_t authority;
1258
    /**
1259
     * method (of the processing request)
1260
     */
1261
    h2o_iovec_t method;
1262
    /**
1263
     * abs-path of the processing request
1264
     */
1265
    h2o_iovec_t path;
1266
    /**
1267
     * offset of '?' within path, or SIZE_MAX if not found
1268
     */
1269
    size_t query_at;
1270
    /**
1271
     * normalized path of the processing request (i.e. no "." or "..", no query)
1272
     */
1273
    h2o_iovec_t path_normalized;
1274
    /**
1275
     * Map of indexes of `path_normalized` into the next character in `path`; built only if `path` required normalization
1276
     */
1277
    size_t *norm_indexes;
1278
    /**
1279
     * authority's prefix matched with `*` against defined hosts
1280
     */
1281
    h2o_iovec_t authority_wildcard_match;
1282
    /**
1283
     * filters assigned per request
1284
     */
1285
    h2o_req_prefilter_t *prefilters;
1286
    /**
1287
     * additional information (becomes available for extension-based dynamic content)
1288
     */
1289
    h2o_filereq_t *filereq;
1290
    /**
1291
     * overrides (maybe NULL)
1292
     */
1293
    h2o_req_overrides_t *overrides;
1294
    /**
1295
     * the HTTP version (represented as 0xMMmm (M=major, m=minor))
1296
     */
1297
    int version;
1298
    /**
1299
     * list of request headers
1300
     */
1301
    h2o_headers_t headers;
1302
    /**
1303
     * the request entity (base == NULL if none), can't be used if the handler is streaming the body
1304
     */
1305
    h2o_iovec_t entity;
1306
    /**
1307
     * amount of request body being received
1308
     */
1309
    size_t req_body_bytes_received;
1310
    /**
1311
     * If different of SIZE_MAX, the numeric value of the received content-length: header
1312
     */
1313
    size_t content_length;
1314
    /**
1315
     * timestamp when the request was processed
1316
     */
1317
    h2o_timestamp_t processed_at;
1318
    /**
1319
     * additional timestamps
1320
     */
1321
    struct {
1322
        struct timeval request_begin_at;
1323
        struct timeval request_body_begin_at;
1324
        struct timeval response_start_at;
1325
        struct timeval response_end_at;
1326
    } timestamps;
1327
    /**
1328
     * proxy stats
1329
     */
1330
    struct {
1331
        struct {
1332
            uint64_t total;
1333
            uint64_t header;
1334
            uint64_t body;
1335
        } bytes_written;
1336
        struct {
1337
            uint64_t total;
1338
            uint64_t header;
1339
            uint64_t body;
1340
        } bytes_read;
1341
        h2o_httpclient_timings_t timestamps;
1342
        h2o_httpclient_conn_properties_t conn;
1343
    } proxy_stats;
1344
    /**
1345
     * the response
1346
     */
1347
    h2o_res_t res;
1348
    /**
1349
     * number of body bytes sent by the generator (excluding headers)
1350
     */
1351
    uint64_t bytes_sent;
1352
    /**
1353
     * number of header bytes sent by the generator
1354
     */
1355
    uint64_t header_bytes_sent;
1356
    /**
1357
     * the number of times the request can be reprocessed (excluding delegation)
1358
     */
1359
    unsigned remaining_reprocesses;
1360
    /**
1361
     * the number of times the request can be delegated
1362
     */
1363
    unsigned remaining_delegations;
1364
1365
    /**
1366
     * environment variables
1367
     */
1368
    h2o_iovec_vector_t env;
1369
1370
    /**
1371
     * error log for the request (`h2o_req_log_error` must be used for error logging)
1372
     */
1373
    h2o_buffer_t *error_logs;
1374
1375
    /**
1376
     * error log redirection called by `h2o_req_log_error`. By default, the error is appended to `error_logs`. The callback is
1377
     * replaced by mruby middleware to send the error log to the rack handler.
1378
     */
1379
    struct {
1380
        void (*cb)(void *data, h2o_iovec_t prefix, h2o_iovec_t msg);
1381
        void *data;
1382
    } error_log_delegate;
1383
1384
    /* flags */
1385
1386
    /**
1387
     * whether or not the connection is persistent.
1388
     * Applications should set this flag to zero in case the connection cannot be kept keep-alive (due to an error etc.)
1389
     */
1390
    unsigned char http1_is_persistent : 1;
1391
    /**
1392
     * whether if the response has been delegated (i.e. reproxied).
1393
     * For delegated responses, redirect responses would be handled internally.
1394
     */
1395
    unsigned char res_is_delegated : 1;
1396
    /**
1397
     * set by the generator if the protocol handler should replay the request upon seeing 425
1398
     */
1399
    unsigned char reprocess_if_too_early : 1;
1400
    /**
1401
     * set by the proxy handler if the http2 upstream refused the stream so the client can retry the request
1402
     */
1403
    unsigned char upstream_refused : 1;
1404
    /**
1405
     * if h2o_process_request has been called
1406
     */
1407
    unsigned char process_called : 1;
1408
    /**
1409
     * Indicates if requested to serve something other than HTTP (e.g., websocket, upgrade, CONNECT, ...) using the streaming API.
1410
     * When the protocol handler returns a successful response, filters are skipped.
1411
     */
1412
    unsigned char is_tunnel_req : 1;
1413
1414
    /**
1415
     * whether if the response should include server-timing header. Logical OR of H2O_SEND_SERVER_TIMING_*
1416
     */
1417
    unsigned send_server_timing;
1418
1419
    /**
1420
     * Whether the producer of the response has explicitly disabled or
1421
     * enabled compression. One of H2O_COMPRESS_HINT_*
1422
     */
1423
    char compress_hint;
1424
1425
    /**
1426
     * the Upgrade request header (or { NULL, 0 } if not available)
1427
     */
1428
    h2o_iovec_t upgrade;
1429
1430
    /**
1431
     * preferred chunk size by the ostream
1432
     */
1433
    size_t preferred_chunk_size;
1434
1435
    /**
1436
     * callback and context for receiving request body (see h2o_handler_t::supports_request_streaming for details)
1437
     */
1438
    struct {
1439
        h2o_write_req_cb cb;
1440
        void *ctx;
1441
    } write_req;
1442
1443
    /**
1444
     * callback and context for receiving more request body (see h2o_handler_t::supports_request_streaming for details)
1445
     */
1446
    h2o_proceed_req_cb proceed_req;
1447
1448
    /**
1449
     * Callbacks for forwarding HTTP/3 Datagrams (RFC 9297).
1450
     * As these callbacks act at the RFC 9297 layer, masque Context IDs (RFC 9298) will be part of the *payload* being exchanged.
1451
     * Write-side is assumed to use `write_req.ctx` for retaining the context if necessary.
1452
     */
1453
    struct {
1454
        h2o_forward_datagram_cb write_, read_;
1455
    } forward_datagram;
1456
1457
    /* internal structure */
1458
    h2o_generator_t *_generator;
1459
    h2o_ostream_t *_ostr_top;
1460
    size_t _next_filter_index;
1461
    h2o_timer_t _timeout_entry;
1462
1463
    /* per-request memory pool (placed at the last since the structure is large) */
1464
    h2o_mem_pool_t pool;
1465
};
1466
1467
typedef struct st_h2o_accept_ctx_t {
1468
    h2o_context_t *ctx;
1469
    h2o_hostconf_t **hosts;
1470
    SSL_CTX *ssl_ctx;
1471
    h2o_iovec_t *http2_origin_frame;
1472
    int expect_proxy_line;
1473
    h2o_multithread_receiver_t *libmemcached_receiver;
1474
} h2o_accept_ctx_t;
1475
1476
/* util */
1477
1478
extern const char h2o_http2_npn_protocols[];
1479
extern const char h2o_npn_protocols[];
1480
extern const h2o_iovec_t h2o_http2_alpn_protocols[];
1481
extern const h2o_iovec_t h2o_alpn_protocols[];
1482
1483
/**
1484
 * accepts a connection
1485
 */
1486
void h2o_accept(h2o_accept_ctx_t *ctx, h2o_socket_t *sock);
1487
/**
1488
 * creates a new connection
1489
 */
1490
h2o_conn_t *h2o_create_connection(size_t sz, h2o_context_t *ctx, h2o_hostconf_t **hosts, struct timeval connected_at,
1491
                                  const h2o_conn_callbacks_t *callbacks);
1492
/**
1493
 * destroys a connection
1494
 */
1495
void h2o_destroy_connection(h2o_conn_t *conn);
1496
/**
1497
 * returns the uuid of the connection as a null-terminated string.
1498
 */
1499
static const char *h2o_conn_get_uuid(h2o_conn_t *conn);
1500
/**
1501
 * returns if the connection is still in early-data state (i.e., if there is a risk of received requests being a replay)
1502
 */
1503
static int h2o_conn_is_early_data(h2o_conn_t *conn);
1504
/**
1505
 * setups accept context for memcached SSL resumption
1506
 */
1507
void h2o_accept_setup_memcached_ssl_resumption(h2o_memcached_context_t *ctx, unsigned expiration);
1508
/**
1509
 * setups accept context for redis SSL resumption
1510
 */
1511
void h2o_accept_setup_redis_ssl_resumption(const char *host, uint16_t port, unsigned expiration, const char *prefix);
1512
/**
1513
 * returns the protocol version (e.g. "HTTP/1.1", "HTTP/2")
1514
 */
1515
size_t h2o_stringify_protocol_version(char *dst, int version);
1516
/**
1517
 * builds the proxy header defined by the PROXY PROTOCOL
1518
 */
1519
size_t h2o_stringify_proxy_header(h2o_conn_t *conn, char *buf);
1520
#define H2O_PROXY_HEADER_MAX_LENGTH                                                                                                \
1521
    (sizeof("PROXY TCP6 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 65535 65535\r\n") - 1)
1522
/**
1523
 * extracts path to be pushed from `Link: rel=preload` header.
1524
 */
1525
void h2o_extract_push_path_from_link_header(h2o_mem_pool_t *pool, const char *value, size_t value_len, h2o_iovec_t base_path,
1526
                                            const h2o_url_scheme_t *input_scheme, h2o_iovec_t input_authority,
1527
                                            const h2o_url_scheme_t *base_scheme, h2o_iovec_t *base_authority,
1528
                                            void (*cb)(void *ctx, const char *path, size_t path_len, int is_critical), void *cb_ctx,
1529
                                            h2o_iovec_t *filtered_value, int allow_cross_origin_push);
1530
/**
1531
 * return a bitmap of compressible types, by parsing the `accept-encoding` header
1532
 */
1533
int h2o_get_compressible_types(const h2o_headers_t *headers);
1534
0
#define H2O_COMPRESSIBLE_GZIP 1
1535
0
#define H2O_COMPRESSIBLE_BROTLI 2
1536
0
#define H2O_COMPRESSIBLE_ZSTD 4
1537
/**
1538
 * builds destination URL or path, by contatenating the prefix and path_info of the request
1539
 */
1540
h2o_iovec_t h2o_build_destination(h2o_req_t *req, const char *prefix, size_t prefix_len, int use_path_normalized);
1541
/**
1542
 * encodes the duration value of the `server-timing` header
1543
 */
1544
void h2o_add_server_timing_header(h2o_req_t *req, int uses_trailer);
1545
/**
1546
 * encodes the duration value of the `server-timing` trailer
1547
 */
1548
h2o_iovec_t h2o_build_server_timing_trailer(h2o_req_t *req, const char *prefix, size_t prefix_len, const char *suffix,
1549
                                            size_t suffix_len);
1550
/**
1551
 * Garbage collects resources kept for future reuse in the current thread. If `now` is set to zero, performs full GC. If a valid
1552
 * pointer is passed to `ctx_optional`, resource associated to the context will be collected as well. This function returns how long
1553
 * the next event loop can block before calling `h2o_cleanup_thread` again, in milliseconds.
1554
 */
1555
uint32_t h2o_cleanup_thread(uint64_t now, h2o_context_t *ctx_optional);
1556
1557
extern uint64_t h2o_connection_id;
1558
1559
/* request */
1560
1561
/**
1562
 * initializes the request structure
1563
 * @param req the request structure
1564
 * @param conn the underlying connection
1565
 * @param src if not NULL, the request structure would be a shallow copy of src
1566
 */
1567
void h2o_init_request(h2o_req_t *req, h2o_conn_t *conn, h2o_req_t *src);
1568
/**
1569
 * releases resources allocated for handling a request
1570
 */
1571
void h2o_dispose_request(h2o_req_t *req);
1572
/**
1573
 * Checks and returns if pseudo headers meet the constraints. This function should be called by each protocol implementation before
1574
 * passing the request to `h2o_process_request`.
1575
 */
1576
int h2o_req_validate_pseudo_headers(h2o_req_t *req);
1577
/**
1578
 * called by the connection layer to start processing a request that is ready
1579
 */
1580
void h2o_process_request(h2o_req_t *req);
1581
/**
1582
 * returns the first handler that will be used for the request
1583
 */
1584
h2o_handler_t *h2o_get_first_handler(h2o_req_t *req);
1585
/**
1586
 * delegates the request to the next handler
1587
 */
1588
void h2o_delegate_request(h2o_req_t *req);
1589
/**
1590
 * calls h2o_delegate_request using zero_timeout callback
1591
 */
1592
void h2o_delegate_request_deferred(h2o_req_t *req);
1593
/**
1594
 * reprocesses a request once more (used for internal redirection)
1595
 */
1596
void h2o_reprocess_request(h2o_req_t *req, h2o_iovec_t method, const h2o_url_scheme_t *scheme, h2o_iovec_t authority,
1597
                           h2o_iovec_t path, h2o_req_overrides_t *overrides, int is_delegated);
1598
/**
1599
 * calls h2o_reprocess_request using zero_timeout callback
1600
 */
1601
void h2o_reprocess_request_deferred(h2o_req_t *req, h2o_iovec_t method, const h2o_url_scheme_t *scheme, h2o_iovec_t authority,
1602
                                    h2o_iovec_t path, h2o_req_overrides_t *overrides, int is_delegated);
1603
/**
1604
 *
1605
 */
1606
void h2o_replay_request(h2o_req_t *req);
1607
/**
1608
 *
1609
 */
1610
void h2o_replay_request_deferred(h2o_req_t *req);
1611
/**
1612
 * called by handlers to set the generator
1613
 * @param req the request
1614
 * @param generator the generator
1615
 */
1616
void h2o_start_response(h2o_req_t *req, h2o_generator_t *generator);
1617
/**
1618
 * called by filters to insert output-stream filters for modifying the response
1619
 * @param req the request
1620
 * @param alignment of the memory to be allocated for the ostream filter
1621
 * @param size of the memory to be allocated for the ostream filter
1622
 * @param slot where the stream should be inserted
1623
 * @return pointer to the ostream filter
1624
 */
1625
h2o_ostream_t *h2o_add_ostream(h2o_req_t *req, size_t alignment, size_t sz, h2o_ostream_t **slot);
1626
/**
1627
 * prepares the request for processing by looking at the method, URI, headers
1628
 */
1629
h2o_hostconf_t *h2o_req_setup(h2o_req_t *req);
1630
/**
1631
 * applies given environment configuration to the request
1632
 */
1633
void h2o_req_apply_env(h2o_req_t *req, h2o_envconf_t *env);
1634
/**
1635
 * binds configurations to the request
1636
 */
1637
void h2o_req_bind_conf(h2o_req_t *req, h2o_hostconf_t *hostconf, h2o_pathconf_t *pathconf);
1638
/**
1639
 *
1640
 */
1641
static int h2o_send_state_is_in_progress(h2o_send_state_t s);
1642
/**
1643
 * Called by the generators to send output.
1644
 * When supplying a partial response (i.e., `state` being set to `H2O_SEND_STATE_IN_PROGRESS`), the caller should wait for the
1645
 * invocation of its `proceed` callback, then invoke `h2o_send` again to supply more data.
1646
 * Note `h2o_send` cannot be called to supply just an empty body in the middle of the stream. It is valid to invoke this callback
1647
 * with an empty body with the intent to supply response headers or the closure of the response.
1648
 * After supplying the full response (i.e., `state` being set to something other than `H2O_SEND_STATE_IN_PROGRESS`), generators
1649
 * should free itself.
1650
 * @param req the request
1651
 * @param bufs an array of buffers
1652
 * @param bufcnt length of the buffers array
1653
 * @param state describes if the output is final, has an error, or is in progress
1654
 */
1655
void h2o_send(h2o_req_t *req, h2o_iovec_t *bufs, size_t bufcnt, h2o_send_state_t state);
1656
/**
1657
 * Same as `h2o_send` but sends `h2o_sendvec_t`s
1658
 */
1659
void h2o_sendvec(h2o_req_t *req, h2o_sendvec_t *vecs, size_t veccnt, h2o_send_state_t state);
1660
/**
1661
 * Wrapper around `h2o_sendvec` that sends the contents of pipe
1662
 */
1663
void h2o_send_from_pipe(h2o_req_t *req, int pipefd, size_t len, h2o_send_state_t send_state);
1664
1665
/**
1666
 * creates an uninitialized prefilter and returns pointer to it
1667
 */
1668
h2o_req_prefilter_t *h2o_add_prefilter(h2o_req_t *req, size_t alignment, size_t sz);
1669
/**
1670
 * requests the next prefilter or filter (if any) to setup the ostream if necessary
1671
 */
1672
static void h2o_setup_next_prefilter(h2o_req_prefilter_t *self, h2o_req_t *req, h2o_ostream_t **slot);
1673
/**
1674
 * requests the next filter (if any) to setup the ostream if necessary
1675
 */
1676
static void h2o_setup_next_ostream(h2o_req_t *req, h2o_ostream_t **slot);
1677
/**
1678
 * called by the ostream filters to send output to the next ostream filter
1679
 * note: ostream filters should free itself after sending the final chunk (i.e. calling the function with is_final set to true)
1680
 * note: ostream filters must not set is_final flag to TRUE unless is_final flag of the do_send callback was set as such
1681
 * @param ostr current ostream filter
1682
 * @param req the request
1683
 * @param bufs an array of buffers
1684
 * @param bufcnt length of the buffers array
1685
 * @param state whether the output is in progress, final, or in error
1686
 */
1687
void h2o_ostream_send_next(h2o_ostream_t *ostream, h2o_req_t *req, h2o_sendvec_t *bufs, size_t bufcnt, h2o_send_state_t state);
1688
/**
1689
 * called by the connection layer to request additional data to the generator
1690
 */
1691
static void h2o_proceed_response(h2o_req_t *req);
1692
void h2o_proceed_response_deferred(h2o_req_t *req);
1693
/**
1694
 * if NULL, supplements h2o_req_t::mime_attr
1695
 */
1696
void h2o_req_fill_mime_attributes(h2o_req_t *req);
1697
/**
1698
 * returns an environment variable
1699
 */
1700
static h2o_iovec_t *h2o_req_getenv(h2o_req_t *req, const char *name, size_t name_len, int allocate_if_not_found);
1701
/**
1702
 * unsets an environment variable
1703
 */
1704
static void h2o_req_unsetenv(h2o_req_t *req, const char *name, size_t name_len);
1705
1706
/* config */
1707
1708
h2o_envconf_t *h2o_config_create_envconf(h2o_envconf_t *src);
1709
void h2o_config_setenv(h2o_envconf_t *envconf, const char *name, const char *value);
1710
void h2o_config_unsetenv(h2o_envconf_t *envconf, const char *name);
1711
1712
/**
1713
 * initializes pathconf
1714
 * @param path path to serve, or NULL if fallback or extension-level
1715
 * @param mimemap mimemap to use, or NULL if fallback or extension-level
1716
 */
1717
void h2o_config_init_pathconf(h2o_pathconf_t *pathconf, h2o_globalconf_t *globalconf, const char *path, h2o_mimemap_t *mimemap);
1718
/**
1719
 *
1720
 */
1721
void h2o_config_dispose_pathconf(h2o_pathconf_t *pathconf);
1722
/**
1723
 * initializes the global configuration
1724
 */
1725
void h2o_config_init(h2o_globalconf_t *config);
1726
/**
1727
 * registers a host context
1728
 */
1729
h2o_hostconf_t *h2o_config_register_host(h2o_globalconf_t *config, h2o_iovec_t host, uint16_t port);
1730
/**
1731
 * registers a path context
1732
 * @param hostconf host-level configuration that the path-level configuration belongs to
1733
 * @param path path
1734
 * @param flags unused and must be set to zero
1735
 *
1736
 * Handling of the path argument has changed in version 2.0 (of the standard server).
1737
 *
1738
 * Before 2.0, the function implicitely added a trailing `/` to the supplied path (if it did not end with a `/`), and when receiving
1739
 * a HTTP request for a matching path without the trailing `/`, libh2o sent a 301 response redirecting the client to a URI with a
1740
 * trailing `/`.
1741
 *
1742
 * Since 2.0, the function retains the exact path given as the argument, and the handlers of the pathconf is invoked if one of the
1743
 * following conditions are met:
1744
 *
1745
 * * request path is an exact match to the configuration path
1746
 * * configuration path does not end with a `/`, and the request path begins with the configuration path followed by a `/`
1747
 */
1748
h2o_pathconf_t *h2o_config_register_path(h2o_hostconf_t *hostconf, const char *path, int flags);
1749
/**
1750
 * registers an extra status handler
1751
 */
1752
void h2o_config_register_status_handler(h2o_globalconf_t *config, h2o_status_handler_t *status_handler);
1753
/**
1754
 * disposes of the resources allocated for the global configuration
1755
 */
1756
void h2o_config_dispose(h2o_globalconf_t *config);
1757
/**
1758
 * creates a handler associated to a given pathconf
1759
 */
1760
h2o_handler_t *h2o_create_handler(h2o_pathconf_t *conf, size_t sz);
1761
/**
1762
 * creates a filter associated to a given pathconf
1763
 */
1764
h2o_filter_t *h2o_create_filter(h2o_pathconf_t *conf, size_t sz);
1765
/**
1766
 * creates a logger associated to a given pathconf
1767
 */
1768
h2o_logger_t *h2o_create_logger(h2o_pathconf_t *conf, size_t sz);
1769
1770
/* context */
1771
1772
/**
1773
 * initializes the context
1774
 */
1775
void h2o_context_init(h2o_context_t *context, h2o_loop_t *loop, h2o_globalconf_t *config);
1776
/**
1777
 * disposes of the resources allocated for the context
1778
 */
1779
void h2o_context_dispose(h2o_context_t *context);
1780
/**
1781
 * requests shutdown to the connections governed by the context
1782
 */
1783
void h2o_context_request_shutdown(h2o_context_t *context);
1784
/**
1785
 *
1786
 */
1787
void h2o_context_init_pathconf_context(h2o_context_t *ctx, h2o_pathconf_t *pathconf);
1788
/**
1789
 *
1790
 */
1791
void h2o_context_dispose_pathconf_context(h2o_context_t *ctx, h2o_pathconf_t *pathconf);
1792
1793
/**
1794
 * returns current timestamp
1795
 * @param ctx the context
1796
 * @param pool memory pool (used when ts != NULL)
1797
 * @param ts buffer to store the timestamp (optional)
1798
 * @return current time in UTC
1799
 */
1800
static h2o_timestamp_t h2o_get_timestamp(h2o_context_t *ctx, h2o_mem_pool_t *pool);
1801
void h2o_context_update_timestamp_string_cache(h2o_context_t *ctx);
1802
/**
1803
 * Closes at most @max_connections_to_close connections that have been inactive for @min_age milliseconds
1804
 */
1805
void h2o_context_close_idle_connections(h2o_context_t *ctx, size_t max_connections_to_close, uint64_t min_age);
1806
/**
1807
 * transition connection state
1808
 */
1809
void h2o_conn_set_state(h2o_conn_t *conn, h2o_conn_state_t state);
1810
/**
1811
 * returns per-module context set
1812
 */
1813
static void *h2o_context_get_handler_context(h2o_context_t *ctx, h2o_handler_t *handler);
1814
/**
1815
 * sets per-module context
1816
 */
1817
static void h2o_context_set_handler_context(h2o_context_t *ctx, h2o_handler_t *handler, void *handler_ctx);
1818
/**
1819
 * returns per-module context set by the on_context_init callback
1820
 */
1821
static void *h2o_context_get_filter_context(h2o_context_t *ctx, h2o_filter_t *filter);
1822
/**
1823
 * sets per-module filter context
1824
 */
1825
static void h2o_context_set_filter_context(h2o_context_t *ctx, h2o_filter_t *filter, void *filter_ctx);
1826
/**
1827
 * returns per-module context set by the on_context_init callback
1828
 */
1829
static void *h2o_context_get_logger_context(h2o_context_t *ctx, h2o_logger_t *logger);
1830
/*
1831
 * return the address associated with the key in the context storage
1832
 */
1833
static void **h2o_context_get_storage(h2o_context_t *ctx, size_t *key, void (*dispose_cb)(void *));
1834
/**
1835
 * provides a new pipe that has O_NONBLOCK set, possibly reusing a cached one that is empty; returns a boolean indicating success
1836
 */
1837
int h2o_context_new_pipe(h2o_context_t *ctx, int fds[2]);
1838
/**
1839
 * returns a pipe to the spare pipe cache
1840
 */
1841
void h2o_context_return_spare_pipe(h2o_context_t *ctx, int fds[2]);
1842
1843
/* built-in generators */
1844
1845
enum {
1846
    /**
1847
     * enforces the http1 protocol handler to close the connection after sending the response
1848
     */
1849
    H2O_SEND_ERROR_HTTP1_CLOSE_CONNECTION = 0x1,
1850
    /**
1851
     * if set, does not flush the registered response headers
1852
     */
1853
    H2O_SEND_ERROR_KEEP_HEADERS = 0x2,
1854
    /**
1855
     * indicates a broken or incomplete HTTP request, and that some fields of `h2o_req_t` e.g., `input` might be NULL
1856
     */
1857
    H2O_SEND_ERROR_BROKEN_REQUEST = 0x04
1858
};
1859
1860
/**
1861
 * Add a `date:` header to the response
1862
 */
1863
void h2o_resp_add_date_header(h2o_req_t *req);
1864
/**
1865
 * Sends the given string as the response. The function copies the string so that the caller can discard it immediately.
1866
 *
1867
 * Be careful of calling the function asynchronously, because there is a chance of the request object getting destroyed before the
1868
 * function is being invoked.  This could happpen for example when the client abruptly closing the connection. There are two ways to
1869
 * detect the destruction:
1870
 *
1871
 * * allocate a memory chunk using the request's memory pool with a destructor that you define; i.e. call `h2o_mem_alloc_shared(
1872
 *   &req->pool, obj_size, my_destructor)`. When the request object is destroyed, `my_destructor` will be invoked as part of the
1873
 *   memory reclamation process.
1874
 * * register the `stop` callback of the generator that is bound to the request. The downside of the approach is that a generator
1875
 *   is not associated to a request until all the response headers become ready to be sent, i.e., when `h2o_start_response` is
1876
 *   called.
1877
 */
1878
void h2o_send_inline(h2o_req_t *req, const char *body, size_t len);
1879
/**
1880
 * sends the given information as an error response to the client. Uses h2o_send_inline internally, so the same restrictions apply.
1881
 */
1882
void h2o_send_error_generic(h2o_req_t *req, int status, const char *reason, const char *body, int flags);
1883
#define H2O_SEND_ERROR_XXX(status)                                                                                                 \
1884
    static inline void h2o_send_error_##status(h2o_req_t *req, const char *reason, const char *body, int flags)                    \
1885
12.8k
    {                                                                                                                              \
1886
12.8k
        req->conn->ctx->emitted_error_status[H2O_STATUS_ERROR_##status]++;                                                         \
1887
12.8k
        h2o_send_error_generic(req, status, reason, body, flags);                                                                  \
1888
12.8k
    }
Unexecuted instantiation: driver.cc:h2o_send_error_400(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver.cc:h2o_send_error_401(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver.cc:h2o_send_error_403(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver.cc:h2o_send_error_404(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver.cc:h2o_send_error_405(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver.cc:h2o_send_error_413(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver.cc:h2o_send_error_416(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver.cc:h2o_send_error_417(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver.cc:h2o_send_error_421(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver.cc:h2o_send_error_500(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver.cc:h2o_send_error_502(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver.cc:h2o_send_error_503(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver_common.cc:h2o_send_error_400(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver_common.cc:h2o_send_error_401(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver_common.cc:h2o_send_error_403(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver_common.cc:h2o_send_error_404(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver_common.cc:h2o_send_error_405(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver_common.cc:h2o_send_error_413(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver_common.cc:h2o_send_error_416(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver_common.cc:h2o_send_error_417(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver_common.cc:h2o_send_error_421(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver_common.cc:h2o_send_error_500(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver_common.cc:h2o_send_error_502(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: driver_common.cc:h2o_send_error_503(st_h2o_req_t*, char const*, char const*, int)
Unexecuted instantiation: config.c:h2o_send_error_400
Unexecuted instantiation: config.c:h2o_send_error_401
Unexecuted instantiation: config.c:h2o_send_error_403
Unexecuted instantiation: config.c:h2o_send_error_404
Unexecuted instantiation: config.c:h2o_send_error_405
Unexecuted instantiation: config.c:h2o_send_error_413
Unexecuted instantiation: config.c:h2o_send_error_416
Unexecuted instantiation: config.c:h2o_send_error_417
Unexecuted instantiation: config.c:h2o_send_error_421
Unexecuted instantiation: config.c:h2o_send_error_500
Unexecuted instantiation: config.c:h2o_send_error_502
Unexecuted instantiation: config.c:h2o_send_error_503
Unexecuted instantiation: configurator.c:h2o_send_error_400
Unexecuted instantiation: configurator.c:h2o_send_error_401
Unexecuted instantiation: configurator.c:h2o_send_error_403
Unexecuted instantiation: configurator.c:h2o_send_error_404
Unexecuted instantiation: configurator.c:h2o_send_error_405
Unexecuted instantiation: configurator.c:h2o_send_error_413
Unexecuted instantiation: configurator.c:h2o_send_error_416
Unexecuted instantiation: configurator.c:h2o_send_error_417
Unexecuted instantiation: configurator.c:h2o_send_error_421
Unexecuted instantiation: configurator.c:h2o_send_error_500
Unexecuted instantiation: configurator.c:h2o_send_error_502
Unexecuted instantiation: configurator.c:h2o_send_error_503
Unexecuted instantiation: context.c:h2o_send_error_400
Unexecuted instantiation: context.c:h2o_send_error_401
Unexecuted instantiation: context.c:h2o_send_error_403
Unexecuted instantiation: context.c:h2o_send_error_404
Unexecuted instantiation: context.c:h2o_send_error_405
Unexecuted instantiation: context.c:h2o_send_error_413
Unexecuted instantiation: context.c:h2o_send_error_416
Unexecuted instantiation: context.c:h2o_send_error_417
Unexecuted instantiation: context.c:h2o_send_error_421
Unexecuted instantiation: context.c:h2o_send_error_500
Unexecuted instantiation: context.c:h2o_send_error_502
Unexecuted instantiation: context.c:h2o_send_error_503
Unexecuted instantiation: headers.c:h2o_send_error_400
Unexecuted instantiation: headers.c:h2o_send_error_401
Unexecuted instantiation: headers.c:h2o_send_error_403
Unexecuted instantiation: headers.c:h2o_send_error_404
Unexecuted instantiation: headers.c:h2o_send_error_405
Unexecuted instantiation: headers.c:h2o_send_error_413
Unexecuted instantiation: headers.c:h2o_send_error_416
Unexecuted instantiation: headers.c:h2o_send_error_417
Unexecuted instantiation: headers.c:h2o_send_error_421
Unexecuted instantiation: headers.c:h2o_send_error_500
Unexecuted instantiation: headers.c:h2o_send_error_502
Unexecuted instantiation: headers.c:h2o_send_error_503
request.c:h2o_send_error_404
Line
Count
Source
1885
9.44k
    {                                                                                                                              \
1886
9.44k
        req->conn->ctx->emitted_error_status[H2O_STATUS_ERROR_##status]++;                                                         \
1887
9.44k
        h2o_send_error_generic(req, status, reason, body, flags);                                                                  \
1888
9.44k
    }
Unexecuted instantiation: request.c:h2o_send_error_502
Unexecuted instantiation: request.c:h2o_send_error_400
Unexecuted instantiation: request.c:h2o_send_error_401
Unexecuted instantiation: request.c:h2o_send_error_403
Unexecuted instantiation: request.c:h2o_send_error_405
Unexecuted instantiation: request.c:h2o_send_error_413
Unexecuted instantiation: request.c:h2o_send_error_416
Unexecuted instantiation: request.c:h2o_send_error_417
Unexecuted instantiation: request.c:h2o_send_error_421
Unexecuted instantiation: request.c:h2o_send_error_500
Unexecuted instantiation: request.c:h2o_send_error_503
Unexecuted instantiation: util.c:h2o_send_error_400
Unexecuted instantiation: util.c:h2o_send_error_401
Unexecuted instantiation: util.c:h2o_send_error_403
Unexecuted instantiation: util.c:h2o_send_error_404
Unexecuted instantiation: util.c:h2o_send_error_405
Unexecuted instantiation: util.c:h2o_send_error_413
Unexecuted instantiation: util.c:h2o_send_error_416
Unexecuted instantiation: util.c:h2o_send_error_417
Unexecuted instantiation: util.c:h2o_send_error_421
Unexecuted instantiation: util.c:h2o_send_error_500
Unexecuted instantiation: util.c:h2o_send_error_502
Unexecuted instantiation: util.c:h2o_send_error_503
Unexecuted instantiation: access_log.c:h2o_send_error_400
Unexecuted instantiation: access_log.c:h2o_send_error_401
Unexecuted instantiation: access_log.c:h2o_send_error_403
Unexecuted instantiation: access_log.c:h2o_send_error_404
Unexecuted instantiation: access_log.c:h2o_send_error_405
Unexecuted instantiation: access_log.c:h2o_send_error_413
Unexecuted instantiation: access_log.c:h2o_send_error_416
Unexecuted instantiation: access_log.c:h2o_send_error_417
Unexecuted instantiation: access_log.c:h2o_send_error_421
Unexecuted instantiation: access_log.c:h2o_send_error_500
Unexecuted instantiation: access_log.c:h2o_send_error_502
Unexecuted instantiation: access_log.c:h2o_send_error_503
Unexecuted instantiation: file.c:h2o_send_error_405
Unexecuted instantiation: file.c:h2o_send_error_503
file.c:h2o_send_error_403
Line
Count
Source
1885
33
    {                                                                                                                              \
1886
33
        req->conn->ctx->emitted_error_status[H2O_STATUS_ERROR_##status]++;                                                         \
1887
33
        h2o_send_error_generic(req, status, reason, body, flags);                                                                  \
1888
33
    }
Unexecuted instantiation: file.c:h2o_send_error_416
Unexecuted instantiation: file.c:h2o_send_error_400
Unexecuted instantiation: file.c:h2o_send_error_401
Unexecuted instantiation: file.c:h2o_send_error_404
Unexecuted instantiation: file.c:h2o_send_error_413
Unexecuted instantiation: file.c:h2o_send_error_417
Unexecuted instantiation: file.c:h2o_send_error_421
Unexecuted instantiation: file.c:h2o_send_error_500
Unexecuted instantiation: file.c:h2o_send_error_502
Unexecuted instantiation: mimemap.c:h2o_send_error_400
Unexecuted instantiation: mimemap.c:h2o_send_error_401
Unexecuted instantiation: mimemap.c:h2o_send_error_403
Unexecuted instantiation: mimemap.c:h2o_send_error_404
Unexecuted instantiation: mimemap.c:h2o_send_error_405
Unexecuted instantiation: mimemap.c:h2o_send_error_413
Unexecuted instantiation: mimemap.c:h2o_send_error_416
Unexecuted instantiation: mimemap.c:h2o_send_error_417
Unexecuted instantiation: mimemap.c:h2o_send_error_421
Unexecuted instantiation: mimemap.c:h2o_send_error_500
Unexecuted instantiation: mimemap.c:h2o_send_error_502
Unexecuted instantiation: mimemap.c:h2o_send_error_503
Unexecuted instantiation: proxy.c:h2o_send_error_400
Unexecuted instantiation: proxy.c:h2o_send_error_401
proxy.c:h2o_send_error_403
Line
Count
Source
1885
5
    {                                                                                                                              \
1886
5
        req->conn->ctx->emitted_error_status[H2O_STATUS_ERROR_##status]++;                                                         \
1887
5
        h2o_send_error_generic(req, status, reason, body, flags);                                                                  \
1888
5
    }
Unexecuted instantiation: proxy.c:h2o_send_error_404
Unexecuted instantiation: proxy.c:h2o_send_error_405
Unexecuted instantiation: proxy.c:h2o_send_error_413
Unexecuted instantiation: proxy.c:h2o_send_error_416
Unexecuted instantiation: proxy.c:h2o_send_error_417
Unexecuted instantiation: proxy.c:h2o_send_error_421
Unexecuted instantiation: proxy.c:h2o_send_error_500
proxy.c:h2o_send_error_502
Line
Count
Source
1885
49
    {                                                                                                                              \
1886
49
        req->conn->ctx->emitted_error_status[H2O_STATUS_ERROR_##status]++;                                                         \
1887
49
        h2o_send_error_generic(req, status, reason, body, flags);                                                                  \
1888
49
    }
Unexecuted instantiation: proxy.c:h2o_send_error_503
http1.c:h2o_send_error_400
Line
Count
Source
1885
1.72k
    {                                                                                                                              \
1886
1.72k
        req->conn->ctx->emitted_error_status[H2O_STATUS_ERROR_##status]++;                                                         \
1887
1.72k
        h2o_send_error_generic(req, status, reason, body, flags);                                                                  \
1888
1.72k
    }
http1.c:h2o_send_error_417
Line
Count
Source
1885
19
    {                                                                                                                              \
1886
19
        req->conn->ctx->emitted_error_status[H2O_STATUS_ERROR_##status]++;                                                         \
1887
19
        h2o_send_error_generic(req, status, reason, body, flags);                                                                  \
1888
19
    }
http1.c:h2o_send_error_405
Line
Count
Source
1885
19
    {                                                                                                                              \
1886
19
        req->conn->ctx->emitted_error_status[H2O_STATUS_ERROR_##status]++;                                                         \
1887
19
        h2o_send_error_generic(req, status, reason, body, flags);                                                                  \
1888
19
    }
Unexecuted instantiation: http1.c:h2o_send_error_401
Unexecuted instantiation: http1.c:h2o_send_error_403
Unexecuted instantiation: http1.c:h2o_send_error_404
Unexecuted instantiation: http1.c:h2o_send_error_413
Unexecuted instantiation: http1.c:h2o_send_error_416
Unexecuted instantiation: http1.c:h2o_send_error_421
Unexecuted instantiation: http1.c:h2o_send_error_500
Unexecuted instantiation: http1.c:h2o_send_error_502
Unexecuted instantiation: http1.c:h2o_send_error_503
connection.c:h2o_send_error_400
Line
Count
Source
1885
1.46k
    {                                                                                                                              \
1886
1.46k
        req->conn->ctx->emitted_error_status[H2O_STATUS_ERROR_##status]++;                                                         \
1887
1.46k
        h2o_send_error_generic(req, status, reason, body, flags);                                                                  \
1888
1.46k
    }
connection.c:h2o_send_error_417
Line
Count
Source
1885
122
    {                                                                                                                              \
1886
122
        req->conn->ctx->emitted_error_status[H2O_STATUS_ERROR_##status]++;                                                         \
1887
122
        h2o_send_error_generic(req, status, reason, body, flags);                                                                  \
1888
122
    }
Unexecuted instantiation: connection.c:h2o_send_error_401
Unexecuted instantiation: connection.c:h2o_send_error_403
Unexecuted instantiation: connection.c:h2o_send_error_404
Unexecuted instantiation: connection.c:h2o_send_error_405
Unexecuted instantiation: connection.c:h2o_send_error_413
Unexecuted instantiation: connection.c:h2o_send_error_416
Unexecuted instantiation: connection.c:h2o_send_error_421
Unexecuted instantiation: connection.c:h2o_send_error_500
Unexecuted instantiation: connection.c:h2o_send_error_502
Unexecuted instantiation: connection.c:h2o_send_error_503
Unexecuted instantiation: scheduler.c:h2o_send_error_400
Unexecuted instantiation: scheduler.c:h2o_send_error_401
Unexecuted instantiation: scheduler.c:h2o_send_error_403
Unexecuted instantiation: scheduler.c:h2o_send_error_404
Unexecuted instantiation: scheduler.c:h2o_send_error_405
Unexecuted instantiation: scheduler.c:h2o_send_error_413
Unexecuted instantiation: scheduler.c:h2o_send_error_416
Unexecuted instantiation: scheduler.c:h2o_send_error_417
Unexecuted instantiation: scheduler.c:h2o_send_error_421
Unexecuted instantiation: scheduler.c:h2o_send_error_500
Unexecuted instantiation: scheduler.c:h2o_send_error_502
Unexecuted instantiation: scheduler.c:h2o_send_error_503
Unexecuted instantiation: stream.c:h2o_send_error_400
Unexecuted instantiation: stream.c:h2o_send_error_401
Unexecuted instantiation: stream.c:h2o_send_error_403
Unexecuted instantiation: stream.c:h2o_send_error_404
Unexecuted instantiation: stream.c:h2o_send_error_405
Unexecuted instantiation: stream.c:h2o_send_error_413
Unexecuted instantiation: stream.c:h2o_send_error_416
Unexecuted instantiation: stream.c:h2o_send_error_417
Unexecuted instantiation: stream.c:h2o_send_error_421
Unexecuted instantiation: stream.c:h2o_send_error_500
Unexecuted instantiation: stream.c:h2o_send_error_502
Unexecuted instantiation: stream.c:h2o_send_error_503
Unexecuted instantiation: http2_debug_state.c:h2o_send_error_400
Unexecuted instantiation: http2_debug_state.c:h2o_send_error_401
Unexecuted instantiation: http2_debug_state.c:h2o_send_error_403
Unexecuted instantiation: http2_debug_state.c:h2o_send_error_404
Unexecuted instantiation: http2_debug_state.c:h2o_send_error_405
Unexecuted instantiation: http2_debug_state.c:h2o_send_error_413
Unexecuted instantiation: http2_debug_state.c:h2o_send_error_416
Unexecuted instantiation: http2_debug_state.c:h2o_send_error_417
Unexecuted instantiation: http2_debug_state.c:h2o_send_error_421
Unexecuted instantiation: http2_debug_state.c:h2o_send_error_500
Unexecuted instantiation: http2_debug_state.c:h2o_send_error_502
Unexecuted instantiation: http2_debug_state.c:h2o_send_error_503
Unexecuted instantiation: common.c:h2o_send_error_400
Unexecuted instantiation: common.c:h2o_send_error_401
Unexecuted instantiation: common.c:h2o_send_error_403
Unexecuted instantiation: common.c:h2o_send_error_404
Unexecuted instantiation: common.c:h2o_send_error_405
Unexecuted instantiation: common.c:h2o_send_error_413
Unexecuted instantiation: common.c:h2o_send_error_416
Unexecuted instantiation: common.c:h2o_send_error_417
Unexecuted instantiation: common.c:h2o_send_error_421
Unexecuted instantiation: common.c:h2o_send_error_500
Unexecuted instantiation: common.c:h2o_send_error_502
Unexecuted instantiation: common.c:h2o_send_error_503
Unexecuted instantiation: server.c:h2o_send_error_400
Unexecuted instantiation: server.c:h2o_send_error_413
Unexecuted instantiation: server.c:h2o_send_error_417
Unexecuted instantiation: server.c:h2o_send_error_401
Unexecuted instantiation: server.c:h2o_send_error_403
Unexecuted instantiation: server.c:h2o_send_error_404
Unexecuted instantiation: server.c:h2o_send_error_405
Unexecuted instantiation: server.c:h2o_send_error_416
Unexecuted instantiation: server.c:h2o_send_error_421
Unexecuted instantiation: server.c:h2o_send_error_500
Unexecuted instantiation: server.c:h2o_send_error_502
Unexecuted instantiation: server.c:h2o_send_error_503
Unexecuted instantiation: http3client.c:h2o_send_error_400
Unexecuted instantiation: http3client.c:h2o_send_error_401
Unexecuted instantiation: http3client.c:h2o_send_error_403
Unexecuted instantiation: http3client.c:h2o_send_error_404
Unexecuted instantiation: http3client.c:h2o_send_error_405
Unexecuted instantiation: http3client.c:h2o_send_error_413
Unexecuted instantiation: http3client.c:h2o_send_error_416
Unexecuted instantiation: http3client.c:h2o_send_error_417
Unexecuted instantiation: http3client.c:h2o_send_error_421
Unexecuted instantiation: http3client.c:h2o_send_error_500
Unexecuted instantiation: http3client.c:h2o_send_error_502
Unexecuted instantiation: http3client.c:h2o_send_error_503
Unexecuted instantiation: absprio.c:h2o_send_error_400
Unexecuted instantiation: absprio.c:h2o_send_error_401
Unexecuted instantiation: absprio.c:h2o_send_error_403
Unexecuted instantiation: absprio.c:h2o_send_error_404
Unexecuted instantiation: absprio.c:h2o_send_error_405
Unexecuted instantiation: absprio.c:h2o_send_error_413
Unexecuted instantiation: absprio.c:h2o_send_error_416
Unexecuted instantiation: absprio.c:h2o_send_error_417
Unexecuted instantiation: absprio.c:h2o_send_error_421
Unexecuted instantiation: absprio.c:h2o_send_error_500
Unexecuted instantiation: absprio.c:h2o_send_error_502
Unexecuted instantiation: absprio.c:h2o_send_error_503
Unexecuted instantiation: logconf.c:h2o_send_error_400
Unexecuted instantiation: logconf.c:h2o_send_error_401
Unexecuted instantiation: logconf.c:h2o_send_error_403
Unexecuted instantiation: logconf.c:h2o_send_error_404
Unexecuted instantiation: logconf.c:h2o_send_error_405
Unexecuted instantiation: logconf.c:h2o_send_error_413
Unexecuted instantiation: logconf.c:h2o_send_error_416
Unexecuted instantiation: logconf.c:h2o_send_error_417
Unexecuted instantiation: logconf.c:h2o_send_error_421
Unexecuted instantiation: logconf.c:h2o_send_error_500
Unexecuted instantiation: logconf.c:h2o_send_error_502
Unexecuted instantiation: logconf.c:h2o_send_error_503
Unexecuted instantiation: compress.c:h2o_send_error_400
Unexecuted instantiation: compress.c:h2o_send_error_401
Unexecuted instantiation: compress.c:h2o_send_error_403
Unexecuted instantiation: compress.c:h2o_send_error_404
Unexecuted instantiation: compress.c:h2o_send_error_405
Unexecuted instantiation: compress.c:h2o_send_error_413
Unexecuted instantiation: compress.c:h2o_send_error_416
Unexecuted instantiation: compress.c:h2o_send_error_417
Unexecuted instantiation: compress.c:h2o_send_error_421
Unexecuted instantiation: compress.c:h2o_send_error_500
Unexecuted instantiation: compress.c:h2o_send_error_502
Unexecuted instantiation: compress.c:h2o_send_error_503
Unexecuted instantiation: gzip.c:h2o_send_error_400
Unexecuted instantiation: gzip.c:h2o_send_error_401
Unexecuted instantiation: gzip.c:h2o_send_error_403
Unexecuted instantiation: gzip.c:h2o_send_error_404
Unexecuted instantiation: gzip.c:h2o_send_error_405
Unexecuted instantiation: gzip.c:h2o_send_error_413
Unexecuted instantiation: gzip.c:h2o_send_error_416
Unexecuted instantiation: gzip.c:h2o_send_error_417
Unexecuted instantiation: gzip.c:h2o_send_error_421
Unexecuted instantiation: gzip.c:h2o_send_error_500
Unexecuted instantiation: gzip.c:h2o_send_error_502
Unexecuted instantiation: gzip.c:h2o_send_error_503
Unexecuted instantiation: headers_util.c:h2o_send_error_400
Unexecuted instantiation: headers_util.c:h2o_send_error_401
Unexecuted instantiation: headers_util.c:h2o_send_error_403
Unexecuted instantiation: headers_util.c:h2o_send_error_404
Unexecuted instantiation: headers_util.c:h2o_send_error_405
Unexecuted instantiation: headers_util.c:h2o_send_error_413
Unexecuted instantiation: headers_util.c:h2o_send_error_416
Unexecuted instantiation: headers_util.c:h2o_send_error_417
Unexecuted instantiation: headers_util.c:h2o_send_error_421
Unexecuted instantiation: headers_util.c:h2o_send_error_500
Unexecuted instantiation: headers_util.c:h2o_send_error_502
Unexecuted instantiation: headers_util.c:h2o_send_error_503
Unexecuted instantiation: qpack.c:h2o_send_error_400
Unexecuted instantiation: qpack.c:h2o_send_error_401
Unexecuted instantiation: qpack.c:h2o_send_error_403
Unexecuted instantiation: qpack.c:h2o_send_error_404
Unexecuted instantiation: qpack.c:h2o_send_error_405
Unexecuted instantiation: qpack.c:h2o_send_error_413
Unexecuted instantiation: qpack.c:h2o_send_error_416
Unexecuted instantiation: qpack.c:h2o_send_error_417
Unexecuted instantiation: qpack.c:h2o_send_error_421
Unexecuted instantiation: qpack.c:h2o_send_error_500
Unexecuted instantiation: qpack.c:h2o_send_error_502
Unexecuted instantiation: qpack.c:h2o_send_error_503
1889
1890
H2O_SEND_ERROR_XXX(400)
1891
H2O_SEND_ERROR_XXX(401)
1892
H2O_SEND_ERROR_XXX(403)
1893
H2O_SEND_ERROR_XXX(404)
1894
H2O_SEND_ERROR_XXX(405)
1895
H2O_SEND_ERROR_XXX(413)
1896
H2O_SEND_ERROR_XXX(416)
1897
H2O_SEND_ERROR_XXX(417)
1898
H2O_SEND_ERROR_XXX(421)
1899
H2O_SEND_ERROR_XXX(500)
1900
H2O_SEND_ERROR_XXX(502)
1901
H2O_SEND_ERROR_XXX(503)
1902
1903
/**
1904
 * sends error response using zero timeout; can be called by output filters while processing the headers.  Uses h2o_send_inline
1905
 * internally, so the same restrictions apply.
1906
 */
1907
void h2o_send_error_deferred(h2o_req_t *req, int status, const char *reason, const char *body, int flags);
1908
/**
1909
 * sends a redirect response.  Uses (the equivalent of) h2o_send_inline internally, so the same restrictions apply.
1910
 */
1911
void h2o_send_redirect(h2o_req_t *req, int status, const char *reason, const char *url, size_t url_len);
1912
/**
1913
 * handles redirect internally.
1914
 */
1915
void h2o_send_redirect_internal(h2o_req_t *req, h2o_iovec_t method, const char *url_str, size_t url_len, int preserve_overrides);
1916
/**
1917
 * returns method to be used after redirection
1918
 */
1919
h2o_iovec_t h2o_get_redirect_method(h2o_iovec_t method, int status);
1920
/**
1921
 * registers push path (if necessary) by parsing a Link header
1922
 * this returns a version of `value` that removes the links that had the `x-http2-push-only` attribute
1923
 */
1924
h2o_iovec_t h2o_push_path_in_link_header(h2o_req_t *req, const char *value, size_t value_len);
1925
/**
1926
 * sends 1xx response
1927
 */
1928
void h2o_send_informational(h2o_req_t *req);
1929
/**
1930
 *
1931
 */
1932
static int h2o_req_can_stream_request(h2o_req_t *req);
1933
/**
1934
 *
1935
 */
1936
static int h2o_req_should_forward_expect(h2o_req_t *req);
1937
/**
1938
 * resolves internal redirect url for dest regarding req's hostconf
1939
 */
1940
int h2o_req_resolve_internal_redirect_url(h2o_req_t *req, h2o_iovec_t dest, h2o_url_t *resolved);
1941
/**
1942
 * logs an error
1943
 */
1944
void h2o_req_log_error(h2o_req_t *req, const char *module, const char *fmt, ...) __attribute__((format(printf, 3, 4)));
1945
void h2o_write_error_log(h2o_iovec_t prefix, h2o_iovec_t msg);
1946
1947
/* log */
1948
1949
enum { H2O_LOGCONF_ESCAPE_APACHE, H2O_LOGCONF_ESCAPE_JSON };
1950
1951
/**
1952
 * compiles a log configuration
1953
 */
1954
h2o_logconf_t *h2o_logconf_compile(const char *fmt, int escape, char *errbuf);
1955
/**
1956
 * disposes of a log configuration
1957
 */
1958
void h2o_logconf_dispose(h2o_logconf_t *logconf);
1959
/**
1960
 * logs a request
1961
 */
1962
char *h2o_log_request(h2o_logconf_t *logconf, h2o_req_t *req, size_t *len, char *buf);
1963
1964
/* proxy */
1965
1966
/**
1967
 * processes a request (by sending the request upstream)
1968
 */
1969
void h2o__proxy_process_request(h2o_req_t *req);
1970
1971
/* mime mapper */
1972
1973
/**
1974
 * initializes the mimemap (the returned chunk is refcounted)
1975
 */
1976
h2o_mimemap_t *h2o_mimemap_create(void);
1977
/**
1978
 * clones a mimemap
1979
 */
1980
h2o_mimemap_t *h2o_mimemap_clone(h2o_mimemap_t *src);
1981
/**
1982
 *
1983
 */
1984
void h2o_mimemap_on_context_init(h2o_mimemap_t *mimemap, h2o_context_t *ctx);
1985
/**
1986
 *
1987
 */
1988
void h2o_mimemap_on_context_dispose(h2o_mimemap_t *mimemap, h2o_context_t *ctx);
1989
/**
1990
 * returns if the map contains a dynamic type
1991
 */
1992
int h2o_mimemap_has_dynamic_type(h2o_mimemap_t *mimemap);
1993
/**
1994
 * sets the default mime-type
1995
 */
1996
void h2o_mimemap_set_default_type(h2o_mimemap_t *mimemap, const char *mime, h2o_mime_attributes_t *attr);
1997
/**
1998
 * adds a mime-type mapping
1999
 */
2000
void h2o_mimemap_define_mimetype(h2o_mimemap_t *mimemap, const char *ext, const char *mime, h2o_mime_attributes_t *attr);
2001
/**
2002
 * adds a mime-type mapping
2003
 */
2004
h2o_mimemap_type_t *h2o_mimemap_define_dynamic(h2o_mimemap_t *mimemap, const char **exts, h2o_globalconf_t *globalconf);
2005
/**
2006
 * removes a mime-type mapping
2007
 */
2008
void h2o_mimemap_remove_type(h2o_mimemap_t *mimemap, const char *ext);
2009
/**
2010
 * clears all mime-type mapping
2011
 */
2012
void h2o_mimemap_clear_types(h2o_mimemap_t *mimemap);
2013
/**
2014
 * sets the default mime-type
2015
 */
2016
h2o_mimemap_type_t *h2o_mimemap_get_default_type(h2o_mimemap_t *mimemap);
2017
/**
2018
 * returns the mime-type corresponding to given extension
2019
 */
2020
h2o_mimemap_type_t *h2o_mimemap_get_type_by_extension(h2o_mimemap_t *mimemap, h2o_iovec_t ext);
2021
/**
2022
 * returns the mime-type corresponding to given mimetype
2023
 */
2024
h2o_mimemap_type_t *h2o_mimemap_get_type_by_mimetype(h2o_mimemap_t *mimemap, h2o_iovec_t mime, int exact_match_only);
2025
/**
2026
 * returns the default mime attributes given a mime type
2027
 */
2028
void h2o_mimemap_get_default_attributes(const char *mime, h2o_mime_attributes_t *attr);
2029
2030
/* various handlers */
2031
2032
/* lib/access_log.c */
2033
2034
typedef struct st_h2o_access_log_filehandle_t h2o_access_log_filehandle_t;
2035
2036
int h2o_access_log_open_log(const char *path);
2037
h2o_access_log_filehandle_t *h2o_access_log_open_handle(const char *path, const char *fmt, int escape);
2038
h2o_logger_t *h2o_access_log_register(h2o_pathconf_t *pathconf, h2o_access_log_filehandle_t *handle);
2039
void h2o_access_log_register_configurator(h2o_globalconf_t *conf);
2040
2041
/* lib/handler/server_timing.c */
2042
void h2o_server_timing_register(h2o_pathconf_t *pathconf, int enforce);
2043
void h2o_server_timing_register_configurator(h2o_globalconf_t *conf);
2044
2045
/* lib/compress.c */
2046
2047
enum { H2O_COMPRESS_FLAG_PARTIAL, H2O_COMPRESS_FLAG_FLUSH, H2O_COMPRESS_FLAG_EOS };
2048
2049
/**
2050
 * compressor context
2051
 */
2052
typedef struct st_h2o_compress_context_t {
2053
    /**
2054
     * name used in content-encoding header
2055
     */
2056
    h2o_iovec_t name;
2057
    /**
2058
     * compress or decompress callback (inbufs are raw buffers)
2059
     */
2060
    h2o_send_state_t (*do_transform)(struct st_h2o_compress_context_t *self, h2o_sendvec_t *inbufs, size_t inbufcnt,
2061
                                     h2o_send_state_t state, h2o_sendvec_t **outbufs, size_t *outbufcnt);
2062
    /**
2063
     * push buffer
2064
     */
2065
    char *push_buf;
2066
} h2o_compress_context_t;
2067
2068
typedef struct st_h2o_compress_args_t {
2069
    size_t min_size;
2070
    struct {
2071
        int quality; /* -1 if disabled */
2072
    } gzip;
2073
    struct {
2074
        int quality; /* -1 if disabled */
2075
    } brotli;
2076
} h2o_compress_args_t;
2077
2078
/**
2079
 * registers the gzip/brotli encoding output filter (added by default, for now)
2080
 */
2081
void h2o_compress_register(h2o_pathconf_t *pathconf, h2o_compress_args_t *args);
2082
/**
2083
 * compresses given chunk
2084
 */
2085
h2o_send_state_t h2o_compress_transform(h2o_compress_context_t *self, h2o_req_t *req, h2o_sendvec_t *inbufs, size_t inbufcnt,
2086
                                        h2o_send_state_t state, h2o_sendvec_t **outbufs, size_t *outbufcnt);
2087
/**
2088
 * instantiates the gzip compressor
2089
 */
2090
h2o_compress_context_t *h2o_compress_gzip_open(h2o_mem_pool_t *pool, int quality);
2091
/**
2092
 * instantiates the gzip decompressor
2093
 */
2094
h2o_compress_context_t *h2o_compress_gunzip_open(h2o_mem_pool_t *pool);
2095
/**
2096
 * instantiates the brotli compressor (only available if H2O_USE_BROTLI is set)
2097
 */
2098
h2o_compress_context_t *h2o_compress_brotli_open(h2o_mem_pool_t *pool, int quality, size_t estimated_cotent_length,
2099
                                                 size_t preferred_chunk_size);
2100
/**
2101
 * registers the configurator for the gzip/brotli output filter
2102
 */
2103
void h2o_compress_register_configurator(h2o_globalconf_t *conf);
2104
2105
/* lib/handler/throttle_resp.c */
2106
/**
2107
 * registers the throttle response filter
2108
 */
2109
void h2o_throttle_resp_register(h2o_pathconf_t *pathconf);
2110
/**
2111
 * configurator
2112
 */
2113
void h2o_throttle_resp_register_configurator(h2o_globalconf_t *conf);
2114
2115
/* lib/errordoc.c */
2116
2117
typedef struct st_h2o_errordoc_t {
2118
    int status;
2119
    h2o_iovec_t url; /* can be relative */
2120
} h2o_errordoc_t;
2121
2122
/**
2123
 * registers the errordocument output filter
2124
 */
2125
void h2o_errordoc_register(h2o_pathconf_t *pathconf, h2o_errordoc_t *errdocs, size_t cnt);
2126
/**
2127
 *
2128
 */
2129
void h2o_errordoc_register_configurator(h2o_globalconf_t *conf);
2130
2131
/* lib/expires.c */
2132
2133
enum { H2O_EXPIRES_MODE_ABSOLUTE, H2O_EXPIRES_MODE_MAX_AGE };
2134
2135
typedef struct st_h2o_expires_args_t {
2136
    int mode;
2137
    union {
2138
        const char *absolute;
2139
        uint64_t max_age;
2140
    } data;
2141
} h2o_expires_args_t;
2142
2143
/**
2144
 * registers a filter that adds an Expires (or Cache-Control) header
2145
 */
2146
void h2o_expires_register(h2o_pathconf_t *pathconf, h2o_expires_args_t *args);
2147
/**
2148
 *
2149
 */
2150
void h2o_expires_register_configurator(h2o_globalconf_t *conf);
2151
2152
/* lib/fastcgi.c */
2153
2154
typedef struct st_h2o_fastcgi_handler_t h2o_fastcgi_handler_t;
2155
2156
#define H2O_DEFAULT_FASTCGI_IO_TIMEOUT 30000
2157
2158
typedef struct st_h2o_fastcgi_config_vars_t {
2159
    uint64_t io_timeout;
2160
    uint64_t keepalive_timeout; /* 0 to disable */
2161
    h2o_iovec_t document_root;  /* .base=NULL if not set */
2162
    int send_delegated_uri;     /* whether to send the rewritten HTTP_HOST & REQUEST_URI by delegation, or the original */
2163
    struct {
2164
        void (*dispose)(h2o_fastcgi_handler_t *handler, void *data);
2165
        void *data;
2166
    } callbacks;
2167
} h2o_fastcgi_config_vars_t;
2168
2169
/**
2170
 * registers the fastcgi handler to the context
2171
 */
2172
h2o_fastcgi_handler_t *h2o_fastcgi_register(h2o_pathconf_t *pathconf, h2o_url_t *upstream, h2o_fastcgi_config_vars_t *vars);
2173
/**
2174
 * registers the fastcgi handler to the context
2175
 */
2176
h2o_fastcgi_handler_t *h2o_fastcgi_register_by_spawnproc(h2o_pathconf_t *pathconf, char **argv, h2o_fastcgi_config_vars_t *vars);
2177
/**
2178
 * registers the configurator
2179
 */
2180
void h2o_fastcgi_register_configurator(h2o_globalconf_t *conf);
2181
2182
/* lib/file.c */
2183
2184
enum {
2185
    H2O_FILE_FLAG_NO_ETAG = 0x1,
2186
    H2O_FILE_FLAG_DIR_LISTING = 0x2,
2187
    H2O_FILE_FLAG_SEND_COMPRESSED = 0x4,
2188
    H2O_FILE_FLAG_GUNZIP = 0x8,
2189
    H2O_FILE_FLAG_IO_URING = 0x16,
2190
};
2191
2192
typedef struct st_h2o_file_handler_t h2o_file_handler_t;
2193
2194
extern const char **h2o_file_default_index_files;
2195
2196
/**
2197
 * sends given file as the response to the client
2198
 */
2199
int h2o_file_send(h2o_req_t *req, int status, const char *reason, const char *path, h2o_iovec_t mime_type, int flags);
2200
/**
2201
 * registers a handler that serves a directory of statically-served files
2202
 * @param pathconf
2203
 * @param virtual_path
2204
 * @param real_path
2205
 * @param index_files optional NULL-terminated list of of filenames to be considered as the "directory-index"
2206
 * @param mimemap the mimemap (h2o_mimemap_create is called internally if the argument is NULL)
2207
 */
2208
h2o_file_handler_t *h2o_file_register(h2o_pathconf_t *pathconf, const char *real_path, const char **index_files,
2209
                                      h2o_mimemap_t *mimemap, int flags);
2210
/**
2211
 * registers a handler that serves a specific file
2212
 * @param pathconf
2213
 * @param virtual_path
2214
 * @param real_path
2215
 * @param index_files optional NULL-terminated list of of filenames to be considered as the "directory-index"
2216
 * @param mimemap the mimemap (h2o_mimemap_create is called internally if the argument is NULL)
2217
 */
2218
h2o_handler_t *h2o_file_register_file(h2o_pathconf_t *pathconf, const char *real_path, h2o_mimemap_type_t *mime_type, int flags);
2219
/**
2220
 * returns the associated mimemap
2221
 */
2222
h2o_mimemap_t *h2o_file_get_mimemap(h2o_file_handler_t *handler);
2223
/**
2224
 * registers the configurator
2225
 */
2226
void h2o_file_register_configurator(h2o_globalconf_t *conf);
2227
2228
/* lib/headers.c */
2229
2230
enum {
2231
    H2O_HEADERS_CMD_NULL,
2232
    H2O_HEADERS_CMD_ADD,                /* adds a new header line */
2233
    H2O_HEADERS_CMD_APPEND,             /* adds a new header line or contenates to the existing header */
2234
    H2O_HEADERS_CMD_MERGE,              /* merges the value into a comma-listed values of the named header */
2235
    H2O_HEADERS_CMD_SET,                /* sets a header line, overwriting the existing one (if any) */
2236
    H2O_HEADERS_CMD_SETIFEMPTY,         /* sets a header line if empty */
2237
    H2O_HEADERS_CMD_UNSET,              /* removes the named header(s) */
2238
    H2O_HEADERS_CMD_UNSETUNLESS,        /* only keeps the named header(s) */
2239
    H2O_HEADERS_CMD_COOKIE_UNSET,       /* removes the named cookie(s) */
2240
    H2O_HEADERS_CMD_COOKIE_UNSETUNLESS, /* only keeps the named cookie(s) */
2241
};
2242
2243
typedef enum h2o_headers_command_when {
2244
    H2O_HEADERS_CMD_WHEN_FINAL,
2245
    H2O_HEADERS_CMD_WHEN_EARLY,
2246
    H2O_HEADERS_CMD_WHEN_ALL,
2247
} h2o_headers_command_when_t;
2248
2249
typedef struct st_h2o_headers_command_arg_t {
2250
    h2o_iovec_t *name; /* maybe a token */
2251
    h2o_iovec_t value;
2252
} h2o_headers_command_arg_t;
2253
2254
struct st_h2o_headers_command_t {
2255
    int cmd;
2256
    h2o_headers_command_arg_t *args;
2257
    size_t num_args;
2258
    h2o_headers_command_when_t when;
2259
};
2260
2261
/**
2262
 * registers a list of commands terminated by cmd==H2O_HEADERS_CMD_NULL
2263
 */
2264
void h2o_headers_register(h2o_pathconf_t *pathconf, h2o_headers_command_t *cmds);
2265
/**
2266
 * returns whether if the given name can be registered to the filter
2267
 */
2268
int h2o_headers_is_prohibited_name(const h2o_token_t *token);
2269
/**
2270
 * registers the configurator
2271
 */
2272
void h2o_headers_register_configurator(h2o_globalconf_t *conf);
2273
2274
/* lib/proxy.c */
2275
2276
typedef struct st_h2o_proxy_config_vars_t {
2277
    uint64_t io_timeout;
2278
    uint64_t connect_timeout;
2279
    uint64_t first_byte_timeout;
2280
    uint64_t keepalive_timeout;
2281
    struct {
2282
        uint64_t name_resolution_delay;
2283
        uint64_t connection_attempt_delay;
2284
    } happy_eyeballs;
2285
    h2o_proxy_expect_mode_t expect_mode;
2286
    unsigned preserve_host : 1;
2287
    unsigned use_proxy_protocol : 1;
2288
    unsigned tunnel_enabled : 1;
2289
    unsigned connect_proxy_status_enabled : 1;
2290
    unsigned support_masque_draft_03 : 1;
2291
    /**
2292
     * a boolean flag if set to true, instructs the proxy to close the frontend h1 connection on behalf of the upstream
2293
     */
2294
    unsigned forward_close_connection : 1;
2295
    h2o_headers_command_t *headers_cmds;
2296
    size_t max_buffer_size;
2297
    struct {
2298
        uint32_t max_concurrent_streams;
2299
        unsigned force_cleartext : 1;
2300
    } http2;
2301
    h2o_httpclient_protocol_ratio_t protocol_ratio;
2302
} h2o_proxy_config_vars_t;
2303
2304
/**
2305
 * registers the reverse proxy handler to the context
2306
 */
2307
void h2o_proxy_register_reverse_proxy(h2o_pathconf_t *pathconf, h2o_proxy_config_vars_t *config, h2o_socketpool_t *sockpool);
2308
/**
2309
 * registers the configurator
2310
 */
2311
void h2o_proxy_register_configurator(h2o_globalconf_t *conf);
2312
2313
/* lib/redirect.c */
2314
2315
typedef struct st_h2o_redirect_handler_t h2o_redirect_handler_t;
2316
2317
/**
2318
 * registers the redirect handler to the context
2319
 * @param pathconf
2320
 * @param internal whether if the redirect is internal or external
2321
 * @param status status code to be sent (e.g. 301, 303, 308, ...)
2322
 * @param prefix prefix of the destitation URL
2323
 */
2324
h2o_redirect_handler_t *h2o_redirect_register(h2o_pathconf_t *pathconf, int internal, int status, const char *prefix);
2325
/**
2326
 * registers the configurator
2327
 */
2328
void h2o_redirect_register_configurator(h2o_globalconf_t *conf);
2329
2330
/* lib/handler/reproxy.c */
2331
2332
typedef struct st_h2o_reproxy_handler_t h2o_reproxy_handler_t;
2333
2334
/**
2335
 * registers the reproxy filter
2336
 */
2337
void h2o_reproxy_register(h2o_pathconf_t *pathconf);
2338
/**
2339
 * registers the configurator
2340
 */
2341
void h2o_reproxy_register_configurator(h2o_globalconf_t *conf);
2342
2343
/* lib/handler/connect.c */
2344
2345
typedef struct st_h2o_connect_acl_entry_t {
2346
    uint8_t allow_; /* true if allow, false if deny */
2347
    enum { H2O_CONNECT_ACL_ADDRESS_ANY, H2O_CONNECT_ACL_ADDRESS_V4, H2O_CONNECT_ACL_ADDRESS_V6 } addr_family;
2348
    union {
2349
        uint32_t v4;
2350
        uint8_t v6[16];
2351
    } addr;
2352
    size_t addr_mask;
2353
    uint16_t port; /* 0 indicates ANY */
2354
} h2o_connect_acl_entry_t;
2355
2356
/**
2357
 * registers the classic connect handler to the context
2358
 */
2359
void h2o_connect_register(h2o_pathconf_t *pathconf, h2o_proxy_config_vars_t *config, h2o_connect_acl_entry_t *acl_entries,
2360
                          size_t num_acl_entries);
2361
/**
2362
 * registers the connect-udp handler (RFC 9298) to the context
2363
 */
2364
void h2o_connect_udp_register(h2o_pathconf_t *pathconf, h2o_proxy_config_vars_t *config, h2o_connect_acl_entry_t *acl_entries,
2365
                              size_t num_acl_entries);
2366
/**
2367
 * Parses a ACL line and stores the result in `output`. If successful, returns NULL, otherwise a string indicating the problem is
2368
 * being returned.
2369
 */
2370
const char *h2o_connect_parse_acl(h2o_connect_acl_entry_t *output, const char *input);
2371
/**
2372
 * Checks if access to given target is permissible, and returns a boolean indicating the result.
2373
 */
2374
int h2o_connect_lookup_acl(h2o_connect_acl_entry_t *acl_entries, size_t num_acl_entries, struct sockaddr *target);
2375
2376
/* lib/handler/status.c */
2377
2378
/**
2379
 * registers the status handler
2380
 */
2381
void h2o_status_register(h2o_pathconf_t *pathconf);
2382
/**
2383
 * registers the duration handler
2384
 */
2385
void h2o_duration_stats_register(h2o_globalconf_t *conf);
2386
/**
2387
 * registers the configurator
2388
 */
2389
void h2o_status_register_configurator(h2o_globalconf_t *conf);
2390
2391
/* lib/handler/headers_util.c */
2392
2393
struct headers_util_add_arg_t;
2394
2395
/**
2396
 * appends a headers command to the list
2397
 */
2398
void h2o_headers_append_command(h2o_headers_command_t **cmds, int cmd, h2o_headers_command_arg_t *args, size_t num_args,
2399
                                h2o_headers_command_when_t when);
2400
/**
2401
 * rewrite headers by the command provided
2402
 */
2403
void h2o_rewrite_headers(h2o_mem_pool_t *pool, h2o_headers_t *headers, h2o_headers_command_t *cmd);
2404
2405
/* lib/handler/http2_debug_state.c */
2406
2407
/**
2408
 * registers the http2 debug state handler
2409
 */
2410
void h2o_http2_debug_state_register(h2o_hostconf_t *hostconf, int hpack_enabled);
2411
/**
2412
 * registers the configurator
2413
 */
2414
void h2o_http2_debug_state_register_configurator(h2o_globalconf_t *conf);
2415
2416
/* lib/handler/conn_state.c */
2417
2418
/**
2419
 *
2420
 */
2421
void h2o_self_trace_register(h2o_pathconf_t *conf);
2422
/**
2423
 *
2424
 */
2425
void h2o_self_trace_register_configurator(h2o_globalconf_t *conf);
2426
2427
/* lib/handler/h2olog.c */
2428
2429
/**
2430
 * registers the h2olog handler, where h2olog(1) connects to.
2431
 */
2432
void h2o_log_register(h2o_hostconf_t *hostconf);
2433
/**
2434
 * registers the h2olog configurator.
2435
 */
2436
void h2o_log_register_configurator(h2o_globalconf_t *conf);
2437
2438
/* inline defs */
2439
2440
#ifdef H2O_NO_64BIT_ATOMICS
2441
extern pthread_mutex_t h2o_conn_id_mutex;
2442
#endif
2443
2444
inline const char *h2o_conn_get_uuid(h2o_conn_t *conn)
2445
0
{
2446
0
    if (conn->_uuid.is_initialized)
2447
0
        return conn->_uuid.str;
2448
0
    h2o_generate_uuidv4(conn->_uuid.str);
2449
0
    conn->_uuid.is_initialized = 1;
2450
0
    return conn->_uuid.str;
2451
0
}
Unexecuted instantiation: driver.cc:h2o_conn_get_uuid(st_h2o_conn_t*)
Unexecuted instantiation: driver_common.cc:h2o_conn_get_uuid(st_h2o_conn_t*)
Unexecuted instantiation: config.c:h2o_conn_get_uuid
Unexecuted instantiation: configurator.c:h2o_conn_get_uuid
Unexecuted instantiation: context.c:h2o_conn_get_uuid
Unexecuted instantiation: headers.c:h2o_conn_get_uuid
Unexecuted instantiation: request.c:h2o_conn_get_uuid
Unexecuted instantiation: util.c:h2o_conn_get_uuid
Unexecuted instantiation: access_log.c:h2o_conn_get_uuid
Unexecuted instantiation: file.c:h2o_conn_get_uuid
Unexecuted instantiation: mimemap.c:h2o_conn_get_uuid
Unexecuted instantiation: proxy.c:h2o_conn_get_uuid
Unexecuted instantiation: http1.c:h2o_conn_get_uuid
Unexecuted instantiation: connection.c:h2o_conn_get_uuid
Unexecuted instantiation: scheduler.c:h2o_conn_get_uuid
Unexecuted instantiation: stream.c:h2o_conn_get_uuid
Unexecuted instantiation: http2_debug_state.c:h2o_conn_get_uuid
Unexecuted instantiation: common.c:h2o_conn_get_uuid
Unexecuted instantiation: server.c:h2o_conn_get_uuid
Unexecuted instantiation: http3client.c:h2o_conn_get_uuid
Unexecuted instantiation: absprio.c:h2o_conn_get_uuid
Unexecuted instantiation: logconf.c:h2o_conn_get_uuid
Unexecuted instantiation: compress.c:h2o_conn_get_uuid
Unexecuted instantiation: gzip.c:h2o_conn_get_uuid
Unexecuted instantiation: headers_util.c:h2o_conn_get_uuid
Unexecuted instantiation: qpack.c:h2o_conn_get_uuid
2452
2453
inline int h2o_conn_is_early_data(h2o_conn_t *conn)
2454
2.41k
{
2455
2.41k
    ptls_t *tls;
2456
2.41k
    if (conn->callbacks->get_ptls == NULL)
2457
0
        return 0;
2458
2.41k
    if ((tls = conn->callbacks->get_ptls(conn)) == NULL)
2459
2.41k
        return 0;
2460
0
    if (ptls_handshake_is_complete(tls))
2461
0
        return 0;
2462
0
    return 1;
2463
0
}
Unexecuted instantiation: driver.cc:h2o_conn_is_early_data(st_h2o_conn_t*)
Unexecuted instantiation: driver_common.cc:h2o_conn_is_early_data(st_h2o_conn_t*)
Unexecuted instantiation: config.c:h2o_conn_is_early_data
Unexecuted instantiation: configurator.c:h2o_conn_is_early_data
Unexecuted instantiation: context.c:h2o_conn_is_early_data
Unexecuted instantiation: headers.c:h2o_conn_is_early_data
Unexecuted instantiation: request.c:h2o_conn_is_early_data
Unexecuted instantiation: util.c:h2o_conn_is_early_data
Unexecuted instantiation: access_log.c:h2o_conn_is_early_data
Unexecuted instantiation: file.c:h2o_conn_is_early_data
Unexecuted instantiation: mimemap.c:h2o_conn_is_early_data
proxy.c:h2o_conn_is_early_data
Line
Count
Source
2454
2.41k
{
2455
2.41k
    ptls_t *tls;
2456
2.41k
    if (conn->callbacks->get_ptls == NULL)
2457
0
        return 0;
2458
2.41k
    if ((tls = conn->callbacks->get_ptls(conn)) == NULL)
2459
2.41k
        return 0;
2460
0
    if (ptls_handshake_is_complete(tls))
2461
0
        return 0;
2462
0
    return 1;
2463
0
}
Unexecuted instantiation: http1.c:h2o_conn_is_early_data
Unexecuted instantiation: connection.c:h2o_conn_is_early_data
Unexecuted instantiation: scheduler.c:h2o_conn_is_early_data
Unexecuted instantiation: stream.c:h2o_conn_is_early_data
Unexecuted instantiation: http2_debug_state.c:h2o_conn_is_early_data
Unexecuted instantiation: common.c:h2o_conn_is_early_data
Unexecuted instantiation: server.c:h2o_conn_is_early_data
Unexecuted instantiation: http3client.c:h2o_conn_is_early_data
Unexecuted instantiation: absprio.c:h2o_conn_is_early_data
Unexecuted instantiation: logconf.c:h2o_conn_is_early_data
Unexecuted instantiation: compress.c:h2o_conn_is_early_data
Unexecuted instantiation: gzip.c:h2o_conn_is_early_data
Unexecuted instantiation: headers_util.c:h2o_conn_is_early_data
Unexecuted instantiation: qpack.c:h2o_conn_is_early_data
2464
2465
inline void h2o_proceed_response(h2o_req_t *req)
2466
1.62k
{
2467
1.62k
    if (req->_generator != NULL) {
2468
1.62k
        req->_generator->proceed(req->_generator, req);
2469
1.62k
    } else {
2470
0
        req->_ostr_top->do_send(req->_ostr_top, req, NULL, 0, H2O_SEND_STATE_FINAL);
2471
0
    }
2472
1.62k
}
Unexecuted instantiation: driver.cc:h2o_proceed_response(st_h2o_req_t*)
Unexecuted instantiation: driver_common.cc:h2o_proceed_response(st_h2o_req_t*)
Unexecuted instantiation: config.c:h2o_proceed_response
Unexecuted instantiation: configurator.c:h2o_proceed_response
Unexecuted instantiation: context.c:h2o_proceed_response
Unexecuted instantiation: headers.c:h2o_proceed_response
Unexecuted instantiation: request.c:h2o_proceed_response
Unexecuted instantiation: util.c:h2o_proceed_response
Unexecuted instantiation: access_log.c:h2o_proceed_response
Unexecuted instantiation: file.c:h2o_proceed_response
Unexecuted instantiation: mimemap.c:h2o_proceed_response
Unexecuted instantiation: proxy.c:h2o_proceed_response
http1.c:h2o_proceed_response
Line
Count
Source
2466
1.45k
{
2467
1.45k
    if (req->_generator != NULL) {
2468
1.45k
        req->_generator->proceed(req->_generator, req);
2469
1.45k
    } else {
2470
0
        req->_ostr_top->do_send(req->_ostr_top, req, NULL, 0, H2O_SEND_STATE_FINAL);
2471
0
    }
2472
1.45k
}
Unexecuted instantiation: connection.c:h2o_proceed_response
Unexecuted instantiation: scheduler.c:h2o_proceed_response
stream.c:h2o_proceed_response
Line
Count
Source
2466
173
{
2467
173
    if (req->_generator != NULL) {
2468
173
        req->_generator->proceed(req->_generator, req);
2469
173
    } else {
2470
0
        req->_ostr_top->do_send(req->_ostr_top, req, NULL, 0, H2O_SEND_STATE_FINAL);
2471
0
    }
2472
173
}
Unexecuted instantiation: http2_debug_state.c:h2o_proceed_response
Unexecuted instantiation: common.c:h2o_proceed_response
Unexecuted instantiation: server.c:h2o_proceed_response
Unexecuted instantiation: http3client.c:h2o_proceed_response
Unexecuted instantiation: absprio.c:h2o_proceed_response
Unexecuted instantiation: logconf.c:h2o_proceed_response
Unexecuted instantiation: compress.c:h2o_proceed_response
Unexecuted instantiation: gzip.c:h2o_proceed_response
Unexecuted instantiation: headers_util.c:h2o_proceed_response
Unexecuted instantiation: qpack.c:h2o_proceed_response
2473
2474
inline h2o_iovec_t *h2o_req_getenv(h2o_req_t *req, const char *name, size_t name_len, int allocate_if_not_found)
2475
0
{
2476
0
    size_t i;
2477
0
    for (i = 0; i != req->env.size; i += 2)
2478
0
        if (h2o_memis(req->env.entries[i].base, req->env.entries[i].len, name, name_len))
2479
0
            return req->env.entries + i + 1;
2480
0
    if (!allocate_if_not_found)
2481
0
        return NULL;
2482
0
    h2o_vector_reserve(&req->pool, &req->env, req->env.size + 2);
2483
0
    req->env.entries[req->env.size++] = h2o_iovec_init(name, name_len);
2484
0
    req->env.entries[req->env.size++] = h2o_iovec_init(NULL, 0);
2485
0
    return req->env.entries + req->env.size - 1;
2486
0
}
Unexecuted instantiation: driver.cc:h2o_req_getenv(st_h2o_req_t*, char const*, unsigned long, int)
Unexecuted instantiation: driver_common.cc:h2o_req_getenv(st_h2o_req_t*, char const*, unsigned long, int)
Unexecuted instantiation: config.c:h2o_req_getenv
Unexecuted instantiation: configurator.c:h2o_req_getenv
Unexecuted instantiation: context.c:h2o_req_getenv
Unexecuted instantiation: headers.c:h2o_req_getenv
Unexecuted instantiation: request.c:h2o_req_getenv
Unexecuted instantiation: util.c:h2o_req_getenv
Unexecuted instantiation: access_log.c:h2o_req_getenv
Unexecuted instantiation: file.c:h2o_req_getenv
Unexecuted instantiation: mimemap.c:h2o_req_getenv
Unexecuted instantiation: proxy.c:h2o_req_getenv
Unexecuted instantiation: http1.c:h2o_req_getenv
Unexecuted instantiation: connection.c:h2o_req_getenv
Unexecuted instantiation: scheduler.c:h2o_req_getenv
Unexecuted instantiation: stream.c:h2o_req_getenv
Unexecuted instantiation: http2_debug_state.c:h2o_req_getenv
Unexecuted instantiation: common.c:h2o_req_getenv
Unexecuted instantiation: server.c:h2o_req_getenv
Unexecuted instantiation: http3client.c:h2o_req_getenv
Unexecuted instantiation: absprio.c:h2o_req_getenv
Unexecuted instantiation: logconf.c:h2o_req_getenv
Unexecuted instantiation: compress.c:h2o_req_getenv
Unexecuted instantiation: gzip.c:h2o_req_getenv
Unexecuted instantiation: headers_util.c:h2o_req_getenv
Unexecuted instantiation: qpack.c:h2o_req_getenv
2487
2488
inline void h2o_req_unsetenv(h2o_req_t *req, const char *name, size_t name_len)
2489
0
{
2490
0
    size_t i;
2491
0
    for (i = 0; i != req->env.size; i += 2)
2492
0
        if (h2o_memis(req->env.entries[i].base, req->env.entries[i].len, name, name_len))
2493
0
            goto Found;
2494
    /* not found */
2495
0
    return;
2496
0
Found:
2497
0
    memmove(req->env.entries + i, req->env.entries + i + 2, req->env.size - i - 2);
2498
0
    req->env.size -= 2;
2499
0
}
Unexecuted instantiation: driver.cc:h2o_req_unsetenv(st_h2o_req_t*, char const*, unsigned long)
Unexecuted instantiation: driver_common.cc:h2o_req_unsetenv(st_h2o_req_t*, char const*, unsigned long)
Unexecuted instantiation: config.c:h2o_req_unsetenv
Unexecuted instantiation: configurator.c:h2o_req_unsetenv
Unexecuted instantiation: context.c:h2o_req_unsetenv
Unexecuted instantiation: headers.c:h2o_req_unsetenv
Unexecuted instantiation: request.c:h2o_req_unsetenv
Unexecuted instantiation: util.c:h2o_req_unsetenv
Unexecuted instantiation: access_log.c:h2o_req_unsetenv
Unexecuted instantiation: file.c:h2o_req_unsetenv
Unexecuted instantiation: mimemap.c:h2o_req_unsetenv
Unexecuted instantiation: proxy.c:h2o_req_unsetenv
Unexecuted instantiation: http1.c:h2o_req_unsetenv
Unexecuted instantiation: connection.c:h2o_req_unsetenv
Unexecuted instantiation: scheduler.c:h2o_req_unsetenv
Unexecuted instantiation: stream.c:h2o_req_unsetenv
Unexecuted instantiation: http2_debug_state.c:h2o_req_unsetenv
Unexecuted instantiation: common.c:h2o_req_unsetenv
Unexecuted instantiation: server.c:h2o_req_unsetenv
Unexecuted instantiation: http3client.c:h2o_req_unsetenv
Unexecuted instantiation: absprio.c:h2o_req_unsetenv
Unexecuted instantiation: logconf.c:h2o_req_unsetenv
Unexecuted instantiation: compress.c:h2o_req_unsetenv
Unexecuted instantiation: gzip.c:h2o_req_unsetenv
Unexecuted instantiation: headers_util.c:h2o_req_unsetenv
Unexecuted instantiation: qpack.c:h2o_req_unsetenv
2500
2501
inline int h2o_send_state_is_in_progress(h2o_send_state_t s)
2502
34.2k
{
2503
34.2k
    return s == H2O_SEND_STATE_IN_PROGRESS;
2504
34.2k
}
Unexecuted instantiation: driver.cc:h2o_send_state_is_in_progress(h2o_send_state)
Unexecuted instantiation: driver_common.cc:h2o_send_state_is_in_progress(h2o_send_state)
Unexecuted instantiation: config.c:h2o_send_state_is_in_progress
Unexecuted instantiation: configurator.c:h2o_send_state_is_in_progress
Unexecuted instantiation: context.c:h2o_send_state_is_in_progress
Unexecuted instantiation: headers.c:h2o_send_state_is_in_progress
request.c:h2o_send_state_is_in_progress
Line
Count
Source
2502
17.0k
{
2503
17.0k
    return s == H2O_SEND_STATE_IN_PROGRESS;
2504
17.0k
}
Unexecuted instantiation: util.c:h2o_send_state_is_in_progress
Unexecuted instantiation: access_log.c:h2o_send_state_is_in_progress
Unexecuted instantiation: file.c:h2o_send_state_is_in_progress
Unexecuted instantiation: mimemap.c:h2o_send_state_is_in_progress
Unexecuted instantiation: proxy.c:h2o_send_state_is_in_progress
http1.c:h2o_send_state_is_in_progress
Line
Count
Source
2502
11.2k
{
2503
11.2k
    return s == H2O_SEND_STATE_IN_PROGRESS;
2504
11.2k
}
Unexecuted instantiation: connection.c:h2o_send_state_is_in_progress
Unexecuted instantiation: scheduler.c:h2o_send_state_is_in_progress
stream.c:h2o_send_state_is_in_progress
Line
Count
Source
2502
5.98k
{
2503
5.98k
    return s == H2O_SEND_STATE_IN_PROGRESS;
2504
5.98k
}
Unexecuted instantiation: http2_debug_state.c:h2o_send_state_is_in_progress
Unexecuted instantiation: common.c:h2o_send_state_is_in_progress
Unexecuted instantiation: server.c:h2o_send_state_is_in_progress
Unexecuted instantiation: http3client.c:h2o_send_state_is_in_progress
Unexecuted instantiation: absprio.c:h2o_send_state_is_in_progress
Unexecuted instantiation: logconf.c:h2o_send_state_is_in_progress
Unexecuted instantiation: compress.c:h2o_send_state_is_in_progress
Unexecuted instantiation: gzip.c:h2o_send_state_is_in_progress
Unexecuted instantiation: headers_util.c:h2o_send_state_is_in_progress
Unexecuted instantiation: qpack.c:h2o_send_state_is_in_progress
2505
2506
inline void h2o_setup_next_ostream(h2o_req_t *req, h2o_ostream_t **slot)
2507
15.4k
{
2508
15.4k
    h2o_filter_t *next;
2509
2510
15.4k
    if (req->_next_filter_index < req->num_filters) {
2511
0
        next = req->filters[req->_next_filter_index++];
2512
0
        next->on_setup_ostream(next, req, slot);
2513
0
    }
2514
15.4k
}
Unexecuted instantiation: driver.cc:h2o_setup_next_ostream(st_h2o_req_t*, st_h2o_ostream_t**)
Unexecuted instantiation: driver_common.cc:h2o_setup_next_ostream(st_h2o_req_t*, st_h2o_ostream_t**)
Unexecuted instantiation: config.c:h2o_setup_next_ostream
Unexecuted instantiation: configurator.c:h2o_setup_next_ostream
Unexecuted instantiation: context.c:h2o_setup_next_ostream
Unexecuted instantiation: headers.c:h2o_setup_next_ostream
request.c:h2o_setup_next_ostream
Line
Count
Source
2507
15.4k
{
2508
15.4k
    h2o_filter_t *next;
2509
2510
15.4k
    if (req->_next_filter_index < req->num_filters) {
2511
0
        next = req->filters[req->_next_filter_index++];
2512
0
        next->on_setup_ostream(next, req, slot);
2513
0
    }
2514
15.4k
}
Unexecuted instantiation: util.c:h2o_setup_next_ostream
Unexecuted instantiation: access_log.c:h2o_setup_next_ostream
Unexecuted instantiation: file.c:h2o_setup_next_ostream
Unexecuted instantiation: mimemap.c:h2o_setup_next_ostream
Unexecuted instantiation: proxy.c:h2o_setup_next_ostream
Unexecuted instantiation: http1.c:h2o_setup_next_ostream
Unexecuted instantiation: connection.c:h2o_setup_next_ostream
Unexecuted instantiation: scheduler.c:h2o_setup_next_ostream
Unexecuted instantiation: stream.c:h2o_setup_next_ostream
Unexecuted instantiation: http2_debug_state.c:h2o_setup_next_ostream
Unexecuted instantiation: common.c:h2o_setup_next_ostream
Unexecuted instantiation: server.c:h2o_setup_next_ostream
Unexecuted instantiation: http3client.c:h2o_setup_next_ostream
Unexecuted instantiation: absprio.c:h2o_setup_next_ostream
Unexecuted instantiation: logconf.c:h2o_setup_next_ostream
Unexecuted instantiation: compress.c:h2o_setup_next_ostream
Unexecuted instantiation: gzip.c:h2o_setup_next_ostream
Unexecuted instantiation: headers_util.c:h2o_setup_next_ostream
Unexecuted instantiation: qpack.c:h2o_setup_next_ostream
2515
2516
inline void h2o_setup_next_prefilter(h2o_req_prefilter_t *self, h2o_req_t *req, h2o_ostream_t **slot)
2517
0
{
2518
0
    h2o_req_prefilter_t *next = self->next;
2519
0
2520
0
    if (next != NULL)
2521
0
        next->on_setup_ostream(next, req, slot);
2522
0
    else
2523
0
        h2o_setup_next_ostream(req, slot);
2524
0
}
Unexecuted instantiation: driver.cc:h2o_setup_next_prefilter(st_h2o_req_prefilter_t*, st_h2o_req_t*, st_h2o_ostream_t**)
Unexecuted instantiation: driver_common.cc:h2o_setup_next_prefilter(st_h2o_req_prefilter_t*, st_h2o_req_t*, st_h2o_ostream_t**)
Unexecuted instantiation: config.c:h2o_setup_next_prefilter
Unexecuted instantiation: configurator.c:h2o_setup_next_prefilter
Unexecuted instantiation: context.c:h2o_setup_next_prefilter
Unexecuted instantiation: headers.c:h2o_setup_next_prefilter
Unexecuted instantiation: request.c:h2o_setup_next_prefilter
Unexecuted instantiation: util.c:h2o_setup_next_prefilter
Unexecuted instantiation: access_log.c:h2o_setup_next_prefilter
Unexecuted instantiation: file.c:h2o_setup_next_prefilter
Unexecuted instantiation: mimemap.c:h2o_setup_next_prefilter
Unexecuted instantiation: proxy.c:h2o_setup_next_prefilter
Unexecuted instantiation: http1.c:h2o_setup_next_prefilter
Unexecuted instantiation: connection.c:h2o_setup_next_prefilter
Unexecuted instantiation: scheduler.c:h2o_setup_next_prefilter
Unexecuted instantiation: stream.c:h2o_setup_next_prefilter
Unexecuted instantiation: http2_debug_state.c:h2o_setup_next_prefilter
Unexecuted instantiation: common.c:h2o_setup_next_prefilter
Unexecuted instantiation: server.c:h2o_setup_next_prefilter
Unexecuted instantiation: http3client.c:h2o_setup_next_prefilter
Unexecuted instantiation: absprio.c:h2o_setup_next_prefilter
Unexecuted instantiation: logconf.c:h2o_setup_next_prefilter
Unexecuted instantiation: compress.c:h2o_setup_next_prefilter
Unexecuted instantiation: gzip.c:h2o_setup_next_prefilter
Unexecuted instantiation: headers_util.c:h2o_setup_next_prefilter
Unexecuted instantiation: qpack.c:h2o_setup_next_prefilter
2525
2526
inline h2o_timestamp_t h2o_get_timestamp(h2o_context_t *ctx, h2o_mem_pool_t *pool)
2527
27.3k
{
2528
27.3k
    time_t prev_sec = ctx->_timestamp_cache.tv_at.tv_sec;
2529
27.3k
    ctx->_timestamp_cache.tv_at = h2o_gettimeofday(ctx->loop);
2530
27.3k
    if (ctx->_timestamp_cache.tv_at.tv_sec != prev_sec)
2531
132
        h2o_context_update_timestamp_string_cache(ctx);
2532
2533
27.3k
    h2o_timestamp_t ts;
2534
27.3k
    ts.at = ctx->_timestamp_cache.tv_at;
2535
27.3k
    h2o_mem_link_shared(pool, ctx->_timestamp_cache.value);
2536
27.3k
    ts.str = ctx->_timestamp_cache.value;
2537
2538
27.3k
    return ts;
2539
27.3k
}
Unexecuted instantiation: driver.cc:h2o_get_timestamp(st_h2o_context_t*, st_h2o_mem_pool_t*)
Unexecuted instantiation: driver_common.cc:h2o_get_timestamp(st_h2o_context_t*, st_h2o_mem_pool_t*)
Unexecuted instantiation: config.c:h2o_get_timestamp
Unexecuted instantiation: configurator.c:h2o_get_timestamp
Unexecuted instantiation: context.c:h2o_get_timestamp
Unexecuted instantiation: headers.c:h2o_get_timestamp
request.c:h2o_get_timestamp
Line
Count
Source
2527
27.3k
{
2528
27.3k
    time_t prev_sec = ctx->_timestamp_cache.tv_at.tv_sec;
2529
27.3k
    ctx->_timestamp_cache.tv_at = h2o_gettimeofday(ctx->loop);
2530
27.3k
    if (ctx->_timestamp_cache.tv_at.tv_sec != prev_sec)
2531
132
        h2o_context_update_timestamp_string_cache(ctx);
2532
2533
27.3k
    h2o_timestamp_t ts;
2534
27.3k
    ts.at = ctx->_timestamp_cache.tv_at;
2535
27.3k
    h2o_mem_link_shared(pool, ctx->_timestamp_cache.value);
2536
27.3k
    ts.str = ctx->_timestamp_cache.value;
2537
2538
27.3k
    return ts;
2539
27.3k
}
Unexecuted instantiation: util.c:h2o_get_timestamp
Unexecuted instantiation: access_log.c:h2o_get_timestamp
Unexecuted instantiation: file.c:h2o_get_timestamp
Unexecuted instantiation: mimemap.c:h2o_get_timestamp
Unexecuted instantiation: proxy.c:h2o_get_timestamp
Unexecuted instantiation: http1.c:h2o_get_timestamp
Unexecuted instantiation: connection.c:h2o_get_timestamp
Unexecuted instantiation: scheduler.c:h2o_get_timestamp
Unexecuted instantiation: stream.c:h2o_get_timestamp
Unexecuted instantiation: http2_debug_state.c:h2o_get_timestamp
Unexecuted instantiation: common.c:h2o_get_timestamp
Unexecuted instantiation: server.c:h2o_get_timestamp
Unexecuted instantiation: http3client.c:h2o_get_timestamp
Unexecuted instantiation: absprio.c:h2o_get_timestamp
Unexecuted instantiation: logconf.c:h2o_get_timestamp
Unexecuted instantiation: compress.c:h2o_get_timestamp
Unexecuted instantiation: gzip.c:h2o_get_timestamp
Unexecuted instantiation: headers_util.c:h2o_get_timestamp
Unexecuted instantiation: qpack.c:h2o_get_timestamp
2540
2541
inline void *h2o_context_get_handler_context(h2o_context_t *ctx, h2o_handler_t *handler)
2542
2.43k
{
2543
2.43k
    return ctx->_module_configs[handler->_config_slot];
2544
2.43k
}
Unexecuted instantiation: driver.cc:h2o_context_get_handler_context(st_h2o_context_t*, st_h2o_handler_t*)
Unexecuted instantiation: driver_common.cc:h2o_context_get_handler_context(st_h2o_context_t*, st_h2o_handler_t*)
Unexecuted instantiation: config.c:h2o_context_get_handler_context
Unexecuted instantiation: configurator.c:h2o_context_get_handler_context
Unexecuted instantiation: context.c:h2o_context_get_handler_context
Unexecuted instantiation: headers.c:h2o_context_get_handler_context
Unexecuted instantiation: request.c:h2o_context_get_handler_context
Unexecuted instantiation: util.c:h2o_context_get_handler_context
Unexecuted instantiation: access_log.c:h2o_context_get_handler_context
Unexecuted instantiation: file.c:h2o_context_get_handler_context
Unexecuted instantiation: mimemap.c:h2o_context_get_handler_context
proxy.c:h2o_context_get_handler_context
Line
Count
Source
2542
2.43k
{
2543
2.43k
    return ctx->_module_configs[handler->_config_slot];
2544
2.43k
}
Unexecuted instantiation: http1.c:h2o_context_get_handler_context
Unexecuted instantiation: connection.c:h2o_context_get_handler_context
Unexecuted instantiation: scheduler.c:h2o_context_get_handler_context
Unexecuted instantiation: stream.c:h2o_context_get_handler_context
Unexecuted instantiation: http2_debug_state.c:h2o_context_get_handler_context
Unexecuted instantiation: common.c:h2o_context_get_handler_context
Unexecuted instantiation: server.c:h2o_context_get_handler_context
Unexecuted instantiation: http3client.c:h2o_context_get_handler_context
Unexecuted instantiation: absprio.c:h2o_context_get_handler_context
Unexecuted instantiation: logconf.c:h2o_context_get_handler_context
Unexecuted instantiation: compress.c:h2o_context_get_handler_context
Unexecuted instantiation: gzip.c:h2o_context_get_handler_context
Unexecuted instantiation: headers_util.c:h2o_context_get_handler_context
Unexecuted instantiation: qpack.c:h2o_context_get_handler_context
2545
2546
inline void h2o_context_set_handler_context(h2o_context_t *ctx, h2o_handler_t *handler, void *handler_ctx)
2547
1
{
2548
1
    ctx->_module_configs[handler->_config_slot] = handler_ctx;
2549
1
}
Unexecuted instantiation: driver.cc:h2o_context_set_handler_context(st_h2o_context_t*, st_h2o_handler_t*, void*)
Unexecuted instantiation: driver_common.cc:h2o_context_set_handler_context(st_h2o_context_t*, st_h2o_handler_t*, void*)
Unexecuted instantiation: config.c:h2o_context_set_handler_context
Unexecuted instantiation: configurator.c:h2o_context_set_handler_context
Unexecuted instantiation: context.c:h2o_context_set_handler_context
Unexecuted instantiation: headers.c:h2o_context_set_handler_context
Unexecuted instantiation: request.c:h2o_context_set_handler_context
Unexecuted instantiation: util.c:h2o_context_set_handler_context
Unexecuted instantiation: access_log.c:h2o_context_set_handler_context
Unexecuted instantiation: file.c:h2o_context_set_handler_context
Unexecuted instantiation: mimemap.c:h2o_context_set_handler_context
proxy.c:h2o_context_set_handler_context
Line
Count
Source
2547
1
{
2548
1
    ctx->_module_configs[handler->_config_slot] = handler_ctx;
2549
1
}
Unexecuted instantiation: http1.c:h2o_context_set_handler_context
Unexecuted instantiation: connection.c:h2o_context_set_handler_context
Unexecuted instantiation: scheduler.c:h2o_context_set_handler_context
Unexecuted instantiation: stream.c:h2o_context_set_handler_context
Unexecuted instantiation: http2_debug_state.c:h2o_context_set_handler_context
Unexecuted instantiation: common.c:h2o_context_set_handler_context
Unexecuted instantiation: server.c:h2o_context_set_handler_context
Unexecuted instantiation: http3client.c:h2o_context_set_handler_context
Unexecuted instantiation: absprio.c:h2o_context_set_handler_context
Unexecuted instantiation: logconf.c:h2o_context_set_handler_context
Unexecuted instantiation: compress.c:h2o_context_set_handler_context
Unexecuted instantiation: gzip.c:h2o_context_set_handler_context
Unexecuted instantiation: headers_util.c:h2o_context_set_handler_context
Unexecuted instantiation: qpack.c:h2o_context_set_handler_context
2550
2551
inline void *h2o_context_get_filter_context(h2o_context_t *ctx, h2o_filter_t *filter)
2552
0
{
2553
0
    return ctx->_module_configs[filter->_config_slot];
2554
0
}
Unexecuted instantiation: driver.cc:h2o_context_get_filter_context(st_h2o_context_t*, st_h2o_filter_t*)
Unexecuted instantiation: driver_common.cc:h2o_context_get_filter_context(st_h2o_context_t*, st_h2o_filter_t*)
Unexecuted instantiation: config.c:h2o_context_get_filter_context
Unexecuted instantiation: configurator.c:h2o_context_get_filter_context
Unexecuted instantiation: context.c:h2o_context_get_filter_context
Unexecuted instantiation: headers.c:h2o_context_get_filter_context
Unexecuted instantiation: request.c:h2o_context_get_filter_context
Unexecuted instantiation: util.c:h2o_context_get_filter_context
Unexecuted instantiation: access_log.c:h2o_context_get_filter_context
Unexecuted instantiation: file.c:h2o_context_get_filter_context
Unexecuted instantiation: mimemap.c:h2o_context_get_filter_context
Unexecuted instantiation: proxy.c:h2o_context_get_filter_context
Unexecuted instantiation: http1.c:h2o_context_get_filter_context
Unexecuted instantiation: connection.c:h2o_context_get_filter_context
Unexecuted instantiation: scheduler.c:h2o_context_get_filter_context
Unexecuted instantiation: stream.c:h2o_context_get_filter_context
Unexecuted instantiation: http2_debug_state.c:h2o_context_get_filter_context
Unexecuted instantiation: common.c:h2o_context_get_filter_context
Unexecuted instantiation: server.c:h2o_context_get_filter_context
Unexecuted instantiation: http3client.c:h2o_context_get_filter_context
Unexecuted instantiation: absprio.c:h2o_context_get_filter_context
Unexecuted instantiation: logconf.c:h2o_context_get_filter_context
Unexecuted instantiation: compress.c:h2o_context_get_filter_context
Unexecuted instantiation: gzip.c:h2o_context_get_filter_context
Unexecuted instantiation: headers_util.c:h2o_context_get_filter_context
Unexecuted instantiation: qpack.c:h2o_context_get_filter_context
2555
2556
inline void h2o_context_set_filter_context(h2o_context_t *ctx, h2o_filter_t *filter, void *filter_ctx)
2557
0
{
2558
0
    ctx->_module_configs[filter->_config_slot] = filter_ctx;
2559
0
}
Unexecuted instantiation: driver.cc:h2o_context_set_filter_context(st_h2o_context_t*, st_h2o_filter_t*, void*)
Unexecuted instantiation: driver_common.cc:h2o_context_set_filter_context(st_h2o_context_t*, st_h2o_filter_t*, void*)
Unexecuted instantiation: config.c:h2o_context_set_filter_context
Unexecuted instantiation: configurator.c:h2o_context_set_filter_context
Unexecuted instantiation: context.c:h2o_context_set_filter_context
Unexecuted instantiation: headers.c:h2o_context_set_filter_context
Unexecuted instantiation: request.c:h2o_context_set_filter_context
Unexecuted instantiation: util.c:h2o_context_set_filter_context
Unexecuted instantiation: access_log.c:h2o_context_set_filter_context
Unexecuted instantiation: file.c:h2o_context_set_filter_context
Unexecuted instantiation: mimemap.c:h2o_context_set_filter_context
Unexecuted instantiation: proxy.c:h2o_context_set_filter_context
Unexecuted instantiation: http1.c:h2o_context_set_filter_context
Unexecuted instantiation: connection.c:h2o_context_set_filter_context
Unexecuted instantiation: scheduler.c:h2o_context_set_filter_context
Unexecuted instantiation: stream.c:h2o_context_set_filter_context
Unexecuted instantiation: http2_debug_state.c:h2o_context_set_filter_context
Unexecuted instantiation: common.c:h2o_context_set_filter_context
Unexecuted instantiation: server.c:h2o_context_set_filter_context
Unexecuted instantiation: http3client.c:h2o_context_set_filter_context
Unexecuted instantiation: absprio.c:h2o_context_set_filter_context
Unexecuted instantiation: logconf.c:h2o_context_set_filter_context
Unexecuted instantiation: compress.c:h2o_context_set_filter_context
Unexecuted instantiation: gzip.c:h2o_context_set_filter_context
Unexecuted instantiation: headers_util.c:h2o_context_set_filter_context
Unexecuted instantiation: qpack.c:h2o_context_set_filter_context
2560
2561
inline void *h2o_context_get_logger_context(h2o_context_t *ctx, h2o_logger_t *logger)
2562
0
{
2563
0
    return ctx->_module_configs[logger->_config_slot];
2564
0
}
Unexecuted instantiation: driver.cc:h2o_context_get_logger_context(st_h2o_context_t*, st_h2o_logger_t*)
Unexecuted instantiation: driver_common.cc:h2o_context_get_logger_context(st_h2o_context_t*, st_h2o_logger_t*)
Unexecuted instantiation: config.c:h2o_context_get_logger_context
Unexecuted instantiation: configurator.c:h2o_context_get_logger_context
Unexecuted instantiation: context.c:h2o_context_get_logger_context
Unexecuted instantiation: headers.c:h2o_context_get_logger_context
Unexecuted instantiation: request.c:h2o_context_get_logger_context
Unexecuted instantiation: util.c:h2o_context_get_logger_context
Unexecuted instantiation: access_log.c:h2o_context_get_logger_context
Unexecuted instantiation: file.c:h2o_context_get_logger_context
Unexecuted instantiation: mimemap.c:h2o_context_get_logger_context
Unexecuted instantiation: proxy.c:h2o_context_get_logger_context
Unexecuted instantiation: http1.c:h2o_context_get_logger_context
Unexecuted instantiation: connection.c:h2o_context_get_logger_context
Unexecuted instantiation: scheduler.c:h2o_context_get_logger_context
Unexecuted instantiation: stream.c:h2o_context_get_logger_context
Unexecuted instantiation: http2_debug_state.c:h2o_context_get_logger_context
Unexecuted instantiation: common.c:h2o_context_get_logger_context
Unexecuted instantiation: server.c:h2o_context_get_logger_context
Unexecuted instantiation: http3client.c:h2o_context_get_logger_context
Unexecuted instantiation: absprio.c:h2o_context_get_logger_context
Unexecuted instantiation: logconf.c:h2o_context_get_logger_context
Unexecuted instantiation: compress.c:h2o_context_get_logger_context
Unexecuted instantiation: gzip.c:h2o_context_get_logger_context
Unexecuted instantiation: headers_util.c:h2o_context_get_logger_context
Unexecuted instantiation: qpack.c:h2o_context_get_logger_context
2565
2566
inline void **h2o_context_get_storage(h2o_context_t *ctx, size_t *key, void (*dispose_cb)(void *))
2567
0
{
2568
    /* SIZE_MAX might not be available in case the file is included from a C++ source file */
2569
0
    size_t size_max = (size_t)-1;
2570
0
    if (*key == size_max)
2571
0
        *key = ctx->storage.size;
2572
0
    if (ctx->storage.size <= *key) {
2573
0
        h2o_vector_reserve(NULL, &ctx->storage, *key + 1);
2574
0
        memset(ctx->storage.entries + ctx->storage.size, 0, (*key + 1 - ctx->storage.size) * sizeof(ctx->storage.entries[0]));
2575
0
        ctx->storage.size = *key + 1;
2576
0
    }
2577
2578
0
    ctx->storage.entries[*key].dispose = dispose_cb;
2579
0
    return &ctx->storage.entries[*key].data;
2580
0
}
Unexecuted instantiation: driver.cc:h2o_context_get_storage(st_h2o_context_t*, unsigned long*, void (*)(void*))
Unexecuted instantiation: driver_common.cc:h2o_context_get_storage(st_h2o_context_t*, unsigned long*, void (*)(void*))
Unexecuted instantiation: config.c:h2o_context_get_storage
Unexecuted instantiation: configurator.c:h2o_context_get_storage
Unexecuted instantiation: context.c:h2o_context_get_storage
Unexecuted instantiation: headers.c:h2o_context_get_storage
Unexecuted instantiation: request.c:h2o_context_get_storage
Unexecuted instantiation: util.c:h2o_context_get_storage
Unexecuted instantiation: access_log.c:h2o_context_get_storage
Unexecuted instantiation: file.c:h2o_context_get_storage
Unexecuted instantiation: mimemap.c:h2o_context_get_storage
Unexecuted instantiation: proxy.c:h2o_context_get_storage
Unexecuted instantiation: http1.c:h2o_context_get_storage
Unexecuted instantiation: connection.c:h2o_context_get_storage
Unexecuted instantiation: scheduler.c:h2o_context_get_storage
Unexecuted instantiation: stream.c:h2o_context_get_storage
Unexecuted instantiation: http2_debug_state.c:h2o_context_get_storage
Unexecuted instantiation: common.c:h2o_context_get_storage
Unexecuted instantiation: server.c:h2o_context_get_storage
Unexecuted instantiation: http3client.c:h2o_context_get_storage
Unexecuted instantiation: absprio.c:h2o_context_get_storage
Unexecuted instantiation: logconf.c:h2o_context_get_storage
Unexecuted instantiation: compress.c:h2o_context_get_storage
Unexecuted instantiation: gzip.c:h2o_context_get_storage
Unexecuted instantiation: headers_util.c:h2o_context_get_storage
Unexecuted instantiation: qpack.c:h2o_context_get_storage
2581
2582
static inline void h2o_context_set_logger_context(h2o_context_t *ctx, h2o_logger_t *logger, void *logger_ctx)
2583
0
{
2584
0
    ctx->_module_configs[logger->_config_slot] = logger_ctx;
2585
0
}
Unexecuted instantiation: driver.cc:h2o_context_set_logger_context(st_h2o_context_t*, st_h2o_logger_t*, void*)
Unexecuted instantiation: driver_common.cc:h2o_context_set_logger_context(st_h2o_context_t*, st_h2o_logger_t*, void*)
Unexecuted instantiation: config.c:h2o_context_set_logger_context
Unexecuted instantiation: configurator.c:h2o_context_set_logger_context
Unexecuted instantiation: context.c:h2o_context_set_logger_context
Unexecuted instantiation: headers.c:h2o_context_set_logger_context
Unexecuted instantiation: request.c:h2o_context_set_logger_context
Unexecuted instantiation: util.c:h2o_context_set_logger_context
Unexecuted instantiation: access_log.c:h2o_context_set_logger_context
Unexecuted instantiation: file.c:h2o_context_set_logger_context
Unexecuted instantiation: mimemap.c:h2o_context_set_logger_context
Unexecuted instantiation: proxy.c:h2o_context_set_logger_context
Unexecuted instantiation: http1.c:h2o_context_set_logger_context
Unexecuted instantiation: connection.c:h2o_context_set_logger_context
Unexecuted instantiation: scheduler.c:h2o_context_set_logger_context
Unexecuted instantiation: stream.c:h2o_context_set_logger_context
Unexecuted instantiation: http2_debug_state.c:h2o_context_set_logger_context
Unexecuted instantiation: common.c:h2o_context_set_logger_context
Unexecuted instantiation: server.c:h2o_context_set_logger_context
Unexecuted instantiation: http3client.c:h2o_context_set_logger_context
Unexecuted instantiation: absprio.c:h2o_context_set_logger_context
Unexecuted instantiation: logconf.c:h2o_context_set_logger_context
Unexecuted instantiation: compress.c:h2o_context_set_logger_context
Unexecuted instantiation: gzip.c:h2o_context_set_logger_context
Unexecuted instantiation: headers_util.c:h2o_context_set_logger_context
Unexecuted instantiation: qpack.c:h2o_context_set_logger_context
2586
2587
inline int h2o_req_can_stream_request(h2o_req_t *req)
2588
1.14k
{
2589
1.14k
    h2o_handler_t *first_handler = h2o_get_first_handler(req);
2590
1.14k
    return first_handler != NULL && first_handler->supports_request_streaming;
2591
1.14k
}
Unexecuted instantiation: driver.cc:h2o_req_can_stream_request(st_h2o_req_t*)
Unexecuted instantiation: driver_common.cc:h2o_req_can_stream_request(st_h2o_req_t*)
Unexecuted instantiation: config.c:h2o_req_can_stream_request
Unexecuted instantiation: configurator.c:h2o_req_can_stream_request
Unexecuted instantiation: context.c:h2o_req_can_stream_request
Unexecuted instantiation: headers.c:h2o_req_can_stream_request
Unexecuted instantiation: request.c:h2o_req_can_stream_request
Unexecuted instantiation: util.c:h2o_req_can_stream_request
Unexecuted instantiation: access_log.c:h2o_req_can_stream_request
Unexecuted instantiation: file.c:h2o_req_can_stream_request
Unexecuted instantiation: mimemap.c:h2o_req_can_stream_request
Unexecuted instantiation: proxy.c:h2o_req_can_stream_request
http1.c:h2o_req_can_stream_request
Line
Count
Source
2588
939
{
2589
939
    h2o_handler_t *first_handler = h2o_get_first_handler(req);
2590
939
    return first_handler != NULL && first_handler->supports_request_streaming;
2591
939
}
connection.c:h2o_req_can_stream_request
Line
Count
Source
2588
207
{
2589
207
    h2o_handler_t *first_handler = h2o_get_first_handler(req);
2590
207
    return first_handler != NULL && first_handler->supports_request_streaming;
2591
207
}
Unexecuted instantiation: scheduler.c:h2o_req_can_stream_request
Unexecuted instantiation: stream.c:h2o_req_can_stream_request
Unexecuted instantiation: http2_debug_state.c:h2o_req_can_stream_request
Unexecuted instantiation: common.c:h2o_req_can_stream_request
Unexecuted instantiation: server.c:h2o_req_can_stream_request
Unexecuted instantiation: http3client.c:h2o_req_can_stream_request
Unexecuted instantiation: absprio.c:h2o_req_can_stream_request
Unexecuted instantiation: logconf.c:h2o_req_can_stream_request
Unexecuted instantiation: compress.c:h2o_req_can_stream_request
Unexecuted instantiation: gzip.c:h2o_req_can_stream_request
Unexecuted instantiation: headers_util.c:h2o_req_can_stream_request
Unexecuted instantiation: qpack.c:h2o_req_can_stream_request
2592
2593
inline int h2o_req_should_forward_expect(h2o_req_t *req)
2594
0
{
2595
    /* Request streaming is necessary to forward expect, otherwise
2596
     * h2o waits to receive whole body from the client (that is what non-streaming mode means)
2597
     * while it waits for 100-continue */
2598
0
    if (!h2o_req_can_stream_request(req))
2599
0
        return 0;
2600
2601
0
    h2o_handler_t *first_handler = h2o_get_first_handler(req);
2602
0
    return first_handler != NULL && first_handler->handles_expect;
2603
0
}
Unexecuted instantiation: driver.cc:h2o_req_should_forward_expect(st_h2o_req_t*)
Unexecuted instantiation: driver_common.cc:h2o_req_should_forward_expect(st_h2o_req_t*)
Unexecuted instantiation: config.c:h2o_req_should_forward_expect
Unexecuted instantiation: configurator.c:h2o_req_should_forward_expect
Unexecuted instantiation: context.c:h2o_req_should_forward_expect
Unexecuted instantiation: headers.c:h2o_req_should_forward_expect
Unexecuted instantiation: request.c:h2o_req_should_forward_expect
Unexecuted instantiation: util.c:h2o_req_should_forward_expect
Unexecuted instantiation: access_log.c:h2o_req_should_forward_expect
Unexecuted instantiation: file.c:h2o_req_should_forward_expect
Unexecuted instantiation: mimemap.c:h2o_req_should_forward_expect
Unexecuted instantiation: proxy.c:h2o_req_should_forward_expect
Unexecuted instantiation: http1.c:h2o_req_should_forward_expect
Unexecuted instantiation: connection.c:h2o_req_should_forward_expect
Unexecuted instantiation: scheduler.c:h2o_req_should_forward_expect
Unexecuted instantiation: stream.c:h2o_req_should_forward_expect
Unexecuted instantiation: http2_debug_state.c:h2o_req_should_forward_expect
Unexecuted instantiation: common.c:h2o_req_should_forward_expect
Unexecuted instantiation: server.c:h2o_req_should_forward_expect
Unexecuted instantiation: http3client.c:h2o_req_should_forward_expect
Unexecuted instantiation: absprio.c:h2o_req_should_forward_expect
Unexecuted instantiation: logconf.c:h2o_req_should_forward_expect
Unexecuted instantiation: compress.c:h2o_req_should_forward_expect
Unexecuted instantiation: gzip.c:h2o_req_should_forward_expect
Unexecuted instantiation: headers_util.c:h2o_req_should_forward_expect
Unexecuted instantiation: qpack.c:h2o_req_should_forward_expect
2604
2605
#define COMPUTE_DURATION(name, from, until)                                                                                        \
2606
    static inline int h2o_time_compute_##name(struct st_h2o_req_t *req, int64_t *delta_usec)                                       \
2607
0
    {                                                                                                                              \
2608
0
        if (h2o_timeval_is_null((from)) || h2o_timeval_is_null((until))) {                                                         \
2609
0
            return 0;                                                                                                              \
2610
0
        }                                                                                                                          \
2611
0
        *delta_usec = h2o_timeval_subtract((from), (until));                                                                       \
2612
0
        return 1;                                                                                                                  \
2613
0
    }
Unexecuted instantiation: driver.cc:h2o_time_compute_connect_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver.cc:h2o_time_compute_header_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver.cc:h2o_time_compute_body_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver.cc:h2o_time_compute_request_total_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver.cc:h2o_time_compute_process_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver.cc:h2o_time_compute_response_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver.cc:h2o_time_compute_total_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver.cc:h2o_time_compute_proxy_idle_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver.cc:h2o_time_compute_proxy_connect_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver.cc:h2o_time_compute_proxy_request_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver.cc:h2o_time_compute_proxy_process_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver.cc:h2o_time_compute_proxy_response_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver.cc:h2o_time_compute_proxy_total_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver_common.cc:h2o_time_compute_connect_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver_common.cc:h2o_time_compute_header_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver_common.cc:h2o_time_compute_body_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver_common.cc:h2o_time_compute_request_total_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver_common.cc:h2o_time_compute_process_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver_common.cc:h2o_time_compute_response_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver_common.cc:h2o_time_compute_total_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver_common.cc:h2o_time_compute_proxy_idle_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver_common.cc:h2o_time_compute_proxy_connect_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver_common.cc:h2o_time_compute_proxy_request_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver_common.cc:h2o_time_compute_proxy_process_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver_common.cc:h2o_time_compute_proxy_response_time(st_h2o_req_t*, long*)
Unexecuted instantiation: driver_common.cc:h2o_time_compute_proxy_total_time(st_h2o_req_t*, long*)
Unexecuted instantiation: config.c:h2o_time_compute_connect_time
Unexecuted instantiation: config.c:h2o_time_compute_header_time
Unexecuted instantiation: config.c:h2o_time_compute_body_time
Unexecuted instantiation: config.c:h2o_time_compute_request_total_time
Unexecuted instantiation: config.c:h2o_time_compute_process_time
Unexecuted instantiation: config.c:h2o_time_compute_response_time
Unexecuted instantiation: config.c:h2o_time_compute_total_time
Unexecuted instantiation: config.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: config.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: config.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: config.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: config.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: config.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: configurator.c:h2o_time_compute_connect_time
Unexecuted instantiation: configurator.c:h2o_time_compute_header_time
Unexecuted instantiation: configurator.c:h2o_time_compute_body_time
Unexecuted instantiation: configurator.c:h2o_time_compute_request_total_time
Unexecuted instantiation: configurator.c:h2o_time_compute_process_time
Unexecuted instantiation: configurator.c:h2o_time_compute_response_time
Unexecuted instantiation: configurator.c:h2o_time_compute_total_time
Unexecuted instantiation: configurator.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: configurator.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: configurator.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: configurator.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: configurator.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: configurator.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: context.c:h2o_time_compute_connect_time
Unexecuted instantiation: context.c:h2o_time_compute_header_time
Unexecuted instantiation: context.c:h2o_time_compute_body_time
Unexecuted instantiation: context.c:h2o_time_compute_request_total_time
Unexecuted instantiation: context.c:h2o_time_compute_process_time
Unexecuted instantiation: context.c:h2o_time_compute_response_time
Unexecuted instantiation: context.c:h2o_time_compute_total_time
Unexecuted instantiation: context.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: context.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: context.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: context.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: context.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: context.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: headers.c:h2o_time_compute_connect_time
Unexecuted instantiation: headers.c:h2o_time_compute_header_time
Unexecuted instantiation: headers.c:h2o_time_compute_body_time
Unexecuted instantiation: headers.c:h2o_time_compute_request_total_time
Unexecuted instantiation: headers.c:h2o_time_compute_process_time
Unexecuted instantiation: headers.c:h2o_time_compute_response_time
Unexecuted instantiation: headers.c:h2o_time_compute_total_time
Unexecuted instantiation: headers.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: headers.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: headers.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: headers.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: headers.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: headers.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: request.c:h2o_time_compute_connect_time
Unexecuted instantiation: request.c:h2o_time_compute_header_time
Unexecuted instantiation: request.c:h2o_time_compute_body_time
Unexecuted instantiation: request.c:h2o_time_compute_request_total_time
Unexecuted instantiation: request.c:h2o_time_compute_process_time
Unexecuted instantiation: request.c:h2o_time_compute_response_time
Unexecuted instantiation: request.c:h2o_time_compute_total_time
Unexecuted instantiation: request.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: request.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: request.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: request.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: request.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: request.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: util.c:h2o_time_compute_connect_time
Unexecuted instantiation: util.c:h2o_time_compute_header_time
Unexecuted instantiation: util.c:h2o_time_compute_body_time
Unexecuted instantiation: util.c:h2o_time_compute_request_total_time
Unexecuted instantiation: util.c:h2o_time_compute_process_time
Unexecuted instantiation: util.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: util.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: util.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: util.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: util.c:h2o_time_compute_response_time
Unexecuted instantiation: util.c:h2o_time_compute_total_time
Unexecuted instantiation: util.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: util.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: access_log.c:h2o_time_compute_connect_time
Unexecuted instantiation: access_log.c:h2o_time_compute_header_time
Unexecuted instantiation: access_log.c:h2o_time_compute_body_time
Unexecuted instantiation: access_log.c:h2o_time_compute_request_total_time
Unexecuted instantiation: access_log.c:h2o_time_compute_process_time
Unexecuted instantiation: access_log.c:h2o_time_compute_response_time
Unexecuted instantiation: access_log.c:h2o_time_compute_total_time
Unexecuted instantiation: access_log.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: access_log.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: access_log.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: access_log.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: access_log.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: access_log.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: file.c:h2o_time_compute_connect_time
Unexecuted instantiation: file.c:h2o_time_compute_header_time
Unexecuted instantiation: file.c:h2o_time_compute_body_time
Unexecuted instantiation: file.c:h2o_time_compute_request_total_time
Unexecuted instantiation: file.c:h2o_time_compute_process_time
Unexecuted instantiation: file.c:h2o_time_compute_response_time
Unexecuted instantiation: file.c:h2o_time_compute_total_time
Unexecuted instantiation: file.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: file.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: file.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: file.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: file.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: file.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: mimemap.c:h2o_time_compute_connect_time
Unexecuted instantiation: mimemap.c:h2o_time_compute_header_time
Unexecuted instantiation: mimemap.c:h2o_time_compute_body_time
Unexecuted instantiation: mimemap.c:h2o_time_compute_request_total_time
Unexecuted instantiation: mimemap.c:h2o_time_compute_process_time
Unexecuted instantiation: mimemap.c:h2o_time_compute_response_time
Unexecuted instantiation: mimemap.c:h2o_time_compute_total_time
Unexecuted instantiation: mimemap.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: mimemap.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: mimemap.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: mimemap.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: mimemap.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: mimemap.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: proxy.c:h2o_time_compute_connect_time
Unexecuted instantiation: proxy.c:h2o_time_compute_header_time
Unexecuted instantiation: proxy.c:h2o_time_compute_body_time
Unexecuted instantiation: proxy.c:h2o_time_compute_request_total_time
Unexecuted instantiation: proxy.c:h2o_time_compute_process_time
Unexecuted instantiation: proxy.c:h2o_time_compute_response_time
Unexecuted instantiation: proxy.c:h2o_time_compute_total_time
Unexecuted instantiation: proxy.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: proxy.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: proxy.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: proxy.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: proxy.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: proxy.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: http1.c:h2o_time_compute_connect_time
Unexecuted instantiation: http1.c:h2o_time_compute_header_time
Unexecuted instantiation: http1.c:h2o_time_compute_body_time
Unexecuted instantiation: http1.c:h2o_time_compute_request_total_time
Unexecuted instantiation: http1.c:h2o_time_compute_process_time
Unexecuted instantiation: http1.c:h2o_time_compute_response_time
Unexecuted instantiation: http1.c:h2o_time_compute_total_time
Unexecuted instantiation: http1.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: http1.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: http1.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: http1.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: http1.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: http1.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: connection.c:h2o_time_compute_connect_time
Unexecuted instantiation: connection.c:h2o_time_compute_header_time
Unexecuted instantiation: connection.c:h2o_time_compute_body_time
Unexecuted instantiation: connection.c:h2o_time_compute_request_total_time
Unexecuted instantiation: connection.c:h2o_time_compute_process_time
Unexecuted instantiation: connection.c:h2o_time_compute_response_time
Unexecuted instantiation: connection.c:h2o_time_compute_total_time
Unexecuted instantiation: connection.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: connection.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: connection.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: connection.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: connection.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: connection.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: scheduler.c:h2o_time_compute_connect_time
Unexecuted instantiation: scheduler.c:h2o_time_compute_header_time
Unexecuted instantiation: scheduler.c:h2o_time_compute_body_time
Unexecuted instantiation: scheduler.c:h2o_time_compute_request_total_time
Unexecuted instantiation: scheduler.c:h2o_time_compute_process_time
Unexecuted instantiation: scheduler.c:h2o_time_compute_response_time
Unexecuted instantiation: scheduler.c:h2o_time_compute_total_time
Unexecuted instantiation: scheduler.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: scheduler.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: scheduler.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: scheduler.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: scheduler.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: scheduler.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: stream.c:h2o_time_compute_connect_time
Unexecuted instantiation: stream.c:h2o_time_compute_header_time
Unexecuted instantiation: stream.c:h2o_time_compute_body_time
Unexecuted instantiation: stream.c:h2o_time_compute_request_total_time
Unexecuted instantiation: stream.c:h2o_time_compute_process_time
Unexecuted instantiation: stream.c:h2o_time_compute_response_time
Unexecuted instantiation: stream.c:h2o_time_compute_total_time
Unexecuted instantiation: stream.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: stream.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: stream.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: stream.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: stream.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: stream.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: http2_debug_state.c:h2o_time_compute_connect_time
Unexecuted instantiation: http2_debug_state.c:h2o_time_compute_header_time
Unexecuted instantiation: http2_debug_state.c:h2o_time_compute_body_time
Unexecuted instantiation: http2_debug_state.c:h2o_time_compute_request_total_time
Unexecuted instantiation: http2_debug_state.c:h2o_time_compute_process_time
Unexecuted instantiation: http2_debug_state.c:h2o_time_compute_response_time
Unexecuted instantiation: http2_debug_state.c:h2o_time_compute_total_time
Unexecuted instantiation: http2_debug_state.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: http2_debug_state.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: http2_debug_state.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: http2_debug_state.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: http2_debug_state.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: http2_debug_state.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: common.c:h2o_time_compute_connect_time
Unexecuted instantiation: common.c:h2o_time_compute_header_time
Unexecuted instantiation: common.c:h2o_time_compute_body_time
Unexecuted instantiation: common.c:h2o_time_compute_request_total_time
Unexecuted instantiation: common.c:h2o_time_compute_process_time
Unexecuted instantiation: common.c:h2o_time_compute_response_time
Unexecuted instantiation: common.c:h2o_time_compute_total_time
Unexecuted instantiation: common.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: common.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: common.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: common.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: common.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: common.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: server.c:h2o_time_compute_connect_time
Unexecuted instantiation: server.c:h2o_time_compute_header_time
Unexecuted instantiation: server.c:h2o_time_compute_body_time
Unexecuted instantiation: server.c:h2o_time_compute_request_total_time
Unexecuted instantiation: server.c:h2o_time_compute_process_time
Unexecuted instantiation: server.c:h2o_time_compute_response_time
Unexecuted instantiation: server.c:h2o_time_compute_total_time
Unexecuted instantiation: server.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: server.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: server.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: server.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: server.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: server.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: http3client.c:h2o_time_compute_connect_time
Unexecuted instantiation: http3client.c:h2o_time_compute_header_time
Unexecuted instantiation: http3client.c:h2o_time_compute_body_time
Unexecuted instantiation: http3client.c:h2o_time_compute_request_total_time
Unexecuted instantiation: http3client.c:h2o_time_compute_process_time
Unexecuted instantiation: http3client.c:h2o_time_compute_response_time
Unexecuted instantiation: http3client.c:h2o_time_compute_total_time
Unexecuted instantiation: http3client.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: http3client.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: http3client.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: http3client.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: http3client.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: http3client.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: absprio.c:h2o_time_compute_connect_time
Unexecuted instantiation: absprio.c:h2o_time_compute_header_time
Unexecuted instantiation: absprio.c:h2o_time_compute_body_time
Unexecuted instantiation: absprio.c:h2o_time_compute_request_total_time
Unexecuted instantiation: absprio.c:h2o_time_compute_process_time
Unexecuted instantiation: absprio.c:h2o_time_compute_response_time
Unexecuted instantiation: absprio.c:h2o_time_compute_total_time
Unexecuted instantiation: absprio.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: absprio.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: absprio.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: absprio.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: absprio.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: absprio.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: logconf.c:h2o_time_compute_connect_time
Unexecuted instantiation: logconf.c:h2o_time_compute_header_time
Unexecuted instantiation: logconf.c:h2o_time_compute_body_time
Unexecuted instantiation: logconf.c:h2o_time_compute_request_total_time
Unexecuted instantiation: logconf.c:h2o_time_compute_process_time
Unexecuted instantiation: logconf.c:h2o_time_compute_response_time
Unexecuted instantiation: logconf.c:h2o_time_compute_total_time
Unexecuted instantiation: logconf.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: logconf.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: logconf.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: logconf.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: logconf.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: logconf.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: compress.c:h2o_time_compute_connect_time
Unexecuted instantiation: compress.c:h2o_time_compute_header_time
Unexecuted instantiation: compress.c:h2o_time_compute_body_time
Unexecuted instantiation: compress.c:h2o_time_compute_request_total_time
Unexecuted instantiation: compress.c:h2o_time_compute_process_time
Unexecuted instantiation: compress.c:h2o_time_compute_response_time
Unexecuted instantiation: compress.c:h2o_time_compute_total_time
Unexecuted instantiation: compress.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: compress.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: compress.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: compress.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: compress.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: compress.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: gzip.c:h2o_time_compute_connect_time
Unexecuted instantiation: gzip.c:h2o_time_compute_header_time
Unexecuted instantiation: gzip.c:h2o_time_compute_body_time
Unexecuted instantiation: gzip.c:h2o_time_compute_request_total_time
Unexecuted instantiation: gzip.c:h2o_time_compute_process_time
Unexecuted instantiation: gzip.c:h2o_time_compute_response_time
Unexecuted instantiation: gzip.c:h2o_time_compute_total_time
Unexecuted instantiation: gzip.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: gzip.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: gzip.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: gzip.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: gzip.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: gzip.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: headers_util.c:h2o_time_compute_connect_time
Unexecuted instantiation: headers_util.c:h2o_time_compute_header_time
Unexecuted instantiation: headers_util.c:h2o_time_compute_body_time
Unexecuted instantiation: headers_util.c:h2o_time_compute_request_total_time
Unexecuted instantiation: headers_util.c:h2o_time_compute_process_time
Unexecuted instantiation: headers_util.c:h2o_time_compute_response_time
Unexecuted instantiation: headers_util.c:h2o_time_compute_total_time
Unexecuted instantiation: headers_util.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: headers_util.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: headers_util.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: headers_util.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: headers_util.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: headers_util.c:h2o_time_compute_proxy_total_time
Unexecuted instantiation: qpack.c:h2o_time_compute_connect_time
Unexecuted instantiation: qpack.c:h2o_time_compute_header_time
Unexecuted instantiation: qpack.c:h2o_time_compute_body_time
Unexecuted instantiation: qpack.c:h2o_time_compute_request_total_time
Unexecuted instantiation: qpack.c:h2o_time_compute_process_time
Unexecuted instantiation: qpack.c:h2o_time_compute_response_time
Unexecuted instantiation: qpack.c:h2o_time_compute_total_time
Unexecuted instantiation: qpack.c:h2o_time_compute_proxy_idle_time
Unexecuted instantiation: qpack.c:h2o_time_compute_proxy_connect_time
Unexecuted instantiation: qpack.c:h2o_time_compute_proxy_request_time
Unexecuted instantiation: qpack.c:h2o_time_compute_proxy_process_time
Unexecuted instantiation: qpack.c:h2o_time_compute_proxy_response_time
Unexecuted instantiation: qpack.c:h2o_time_compute_proxy_total_time
2614
2615
COMPUTE_DURATION(connect_time, &req->conn->connected_at, &req->timestamps.request_begin_at)
2616
COMPUTE_DURATION(header_time, &req->timestamps.request_begin_at,
2617
                 h2o_timeval_is_null(&req->timestamps.request_body_begin_at) ? &req->processed_at.at
2618
                                                                             : &req->timestamps.request_body_begin_at)
2619
COMPUTE_DURATION(body_time,
2620
                 h2o_timeval_is_null(&req->timestamps.request_body_begin_at) ? &req->processed_at.at
2621
                                                                             : &req->timestamps.request_body_begin_at,
2622
                 &req->processed_at.at)
2623
COMPUTE_DURATION(request_total_time, &req->timestamps.request_begin_at, &req->processed_at.at)
2624
COMPUTE_DURATION(process_time, &req->processed_at.at, &req->timestamps.response_start_at)
2625
COMPUTE_DURATION(response_time, &req->timestamps.response_start_at, &req->timestamps.response_end_at)
2626
COMPUTE_DURATION(total_time, &req->timestamps.request_begin_at, &req->timestamps.response_end_at)
2627
2628
COMPUTE_DURATION(proxy_idle_time, &req->timestamps.request_begin_at, &req->proxy_stats.timestamps.start_at)
2629
COMPUTE_DURATION(proxy_connect_time, &req->proxy_stats.timestamps.start_at, &req->proxy_stats.timestamps.request_begin_at)
2630
COMPUTE_DURATION(proxy_request_time, &req->proxy_stats.timestamps.request_begin_at, &req->proxy_stats.timestamps.request_end_at)
2631
COMPUTE_DURATION(proxy_process_time, &req->proxy_stats.timestamps.request_end_at, &req->proxy_stats.timestamps.response_start_at)
2632
COMPUTE_DURATION(proxy_response_time, &req->proxy_stats.timestamps.response_start_at, &req->proxy_stats.timestamps.response_end_at)
2633
COMPUTE_DURATION(proxy_total_time, &req->proxy_stats.timestamps.request_begin_at, &req->proxy_stats.timestamps.response_end_at)
2634
2635
#undef COMPUTE_DURATION
2636
2637
#ifdef __cplusplus
2638
}
2639
#endif
2640
2641
#endif