1 /*
2  * Copyright (c) 2018 Fastly, Kazuho Oku
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__qpack_h
23 #define h2o__qpack_h
24 
25 #include "h2o/hpack.h"
26 
27 typedef struct st_h2o_qpack_decoder_t h2o_qpack_decoder_t;
28 typedef struct st_h2o_qpack_encoder_t h2o_qpack_encoder_t;
29 
30 extern const char *h2o_qpack_err_header_name_too_long;
31 extern const char *h2o_qpack_err_header_value_too_long;
32 extern const char *h2o_qpack_err_header_exceeds_table_size;
33 extern const char *h2o_qpack_err_invalid_max_size;
34 extern const char *h2o_qpack_err_invalid_static_reference;
35 extern const char *h2o_qpack_err_invalid_dynamic_reference;
36 extern const char *h2o_qpack_err_invalid_duplicate;
37 extern const char *h2o_qpack_err_invalid_pseudo_header;
38 
39 h2o_qpack_decoder_t *h2o_qpack_create_decoder(uint32_t header_table_size, uint16_t max_blocked);
40 void h2o_qpack_destroy_decoder(h2o_qpack_decoder_t *qpack);
41 int h2o_qpack_decoder_handle_input(h2o_qpack_decoder_t *qpack, int64_t **unblocked_stream_ids, size_t *num_unblocked,
42                                    const uint8_t **src, const uint8_t *src_end, const char **err_desc);
43 size_t h2o_qpack_decoder_send_state_sync(h2o_qpack_decoder_t *qpack, uint8_t *outbuf);
44 size_t h2o_qpack_decoder_send_stream_cancel(h2o_qpack_decoder_t *qpack, uint8_t *outbuf, int64_t stream_id);
45 
46 /**
47  * Parses a QPACK request. The input should be the *payload* of the HTTP/3 HEADERS frame.
48  */
49 int h2o_qpack_parse_request(h2o_mem_pool_t *pool, h2o_qpack_decoder_t *qpack, int64_t stream_id, h2o_iovec_t *method,
50                             const h2o_url_scheme_t **scheme, h2o_iovec_t *authority, h2o_iovec_t *path, h2o_headers_t *headers,
51                             int *pseudo_header_exists_map, size_t *content_length, h2o_cache_digests_t **digests,
52                             h2o_iovec_t *datagram_flow_id, uint8_t *outbuf, size_t *outbufsize, const uint8_t *src, size_t len,
53                             const char **err_desc);
54 /**
55  * Parses a QPACK response. The input should be the *payload* of the HTTP/3 HEADERS frame. `outbuf` should be at least
56  * H2O_HPACK_ENCODE_INT_MAX_LENGTH long.
57  */
58 int h2o_qpack_parse_response(h2o_mem_pool_t *pool, h2o_qpack_decoder_t *qpack, int64_t stream_id, int *status,
59                              h2o_headers_t *headers, h2o_iovec_t *datagram_flow_id, uint8_t *outbuf, size_t *outbufsize,
60                              const uint8_t *src, size_t len, const char **err_desc);
61 
62 h2o_qpack_encoder_t *h2o_qpack_create_encoder(uint32_t header_table_size, uint16_t max_blocked);
63 void h2o_qpack_destroy_encoder(h2o_qpack_encoder_t *qpack);
64 /**
65  * Handles packets sent to the QPACK encoder (i.e., the bytes carried by the "decoder" stream)
66  * @param qpack can be NULL
67  */
68 int h2o_qpack_encoder_handle_input(h2o_qpack_encoder_t *qpack, const uint8_t **src, const uint8_t *src_end, const char **err_desc);
69 /**
70  * Flattens a QPACK request. The output includes the HTTP/3 frame header.
71  * @param encoder_buf optional parameter pointing to buffer to store encoder stream data. Set to NULL to avoid blocking.
72  */
73 h2o_iovec_t h2o_qpack_flatten_request(h2o_qpack_encoder_t *qpack, h2o_mem_pool_t *pool, int64_t stream_id,
74                                       h2o_byte_vector_t *encoder_buf, h2o_iovec_t method, const h2o_url_scheme_t *scheme,
75                                       h2o_iovec_t authority, h2o_iovec_t path, const h2o_header_t *headers, size_t num_headers,
76                                       h2o_iovec_t datagram_flow_id);
77 /**
78  * Flattens a QPACK response. The output includes the HTTP/3 frame header.
79  */
80 h2o_iovec_t h2o_qpack_flatten_response(h2o_qpack_encoder_t *qpack, h2o_mem_pool_t *pool, int64_t stream_id,
81                                        h2o_byte_vector_t *encoder_buf, int status, const h2o_header_t *headers, size_t num_headers,
82                                        const h2o_iovec_t *server_name, size_t content_length, h2o_iovec_t datagram_flow_id);
83 
84 #endif
85