blob: 7345d2f5739754d282a467ea22fa3565ad2b3d72 [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
Ed Tanousfca2cbe2021-01-28 14:49:59 -08003#pragma once
4
5extern "C"
6{
7#include <nghttp2/nghttp2.h>
8}
9
10#include "logging.hpp"
11
12#include <span>
13
14/* This file contains RAII compatible adapters for nghttp2 structures. They
15 * attempt to be as close to a direct call as possible, while keeping the RAII
Ed Tanousa93163a2024-03-25 11:20:18 -070016 * lifetime safety for the various classes. Because of this, they use the same
17 * naming as nghttp2, so ignore naming violations.
18 */
19
20// NOLINTBEGIN(readability-identifier-naming,
21// readability-make-member-function-const)
Ed Tanousfca2cbe2021-01-28 14:49:59 -080022
23struct nghttp2_session;
24
25struct nghttp2_session_callbacks
26{
27 friend nghttp2_session;
28 nghttp2_session_callbacks()
29 {
30 nghttp2_session_callbacks_new(&ptr);
31 }
32
33 ~nghttp2_session_callbacks()
34 {
35 nghttp2_session_callbacks_del(ptr);
36 }
37
38 nghttp2_session_callbacks(const nghttp2_session_callbacks&) = delete;
39 nghttp2_session_callbacks&
40 operator=(const nghttp2_session_callbacks&) = delete;
41 nghttp2_session_callbacks(nghttp2_session_callbacks&&) = delete;
42 nghttp2_session_callbacks& operator=(nghttp2_session_callbacks&&) = delete;
43
44 void setSendCallback(nghttp2_send_callback sendCallback)
45 {
46 nghttp2_session_callbacks_set_send_callback(ptr, sendCallback);
47 }
48
49 void setOnFrameRecvCallback(nghttp2_on_frame_recv_callback recvCallback)
50 {
51 nghttp2_session_callbacks_set_on_frame_recv_callback(ptr, recvCallback);
52 }
53
54 void setOnStreamCloseCallback(nghttp2_on_stream_close_callback onClose)
55 {
56 nghttp2_session_callbacks_set_on_stream_close_callback(ptr, onClose);
57 }
58
59 void setOnHeaderCallback(nghttp2_on_header_callback onHeader)
60 {
61 nghttp2_session_callbacks_set_on_header_callback(ptr, onHeader);
62 }
63
64 void setOnBeginHeadersCallback(
65 nghttp2_on_begin_headers_callback onBeginHeaders)
66 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040067 nghttp2_session_callbacks_set_on_begin_headers_callback(
68 ptr, onBeginHeaders);
Ed Tanousfca2cbe2021-01-28 14:49:59 -080069 }
70
71 void setSendDataCallback(nghttp2_send_data_callback onSendData)
72 {
73 nghttp2_session_callbacks_set_send_data_callback(ptr, onSendData);
74 }
75 void setBeforeFrameSendCallback(
76 nghttp2_before_frame_send_callback beforeSendFrame)
77 {
78 nghttp2_session_callbacks_set_before_frame_send_callback(
79 ptr, beforeSendFrame);
80 }
81 void
82 setAfterFrameSendCallback(nghttp2_on_frame_send_callback afterSendFrame)
83 {
84 nghttp2_session_callbacks_set_on_frame_send_callback(ptr,
85 afterSendFrame);
86 }
87 void setAfterFrameNoSendCallback(
88 nghttp2_on_frame_not_send_callback afterSendFrame)
89 {
90 nghttp2_session_callbacks_set_on_frame_not_send_callback(
91 ptr, afterSendFrame);
92 }
93
Ed Tanous325310d2024-03-15 09:05:04 -070094 void setOnDataChunkRecvCallback(
95 nghttp2_on_data_chunk_recv_callback afterDataChunkRecv)
96 {
97 nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
98 ptr, afterDataChunkRecv);
99 }
100
Ed Tanousfca2cbe2021-01-28 14:49:59 -0800101 private:
102 nghttp2_session_callbacks* get()
103 {
104 return ptr;
105 }
106
107 nghttp2_session_callbacks* ptr = nullptr;
108};
109
110struct nghttp2_session
111{
112 explicit nghttp2_session(nghttp2_session_callbacks& callbacks)
113 {
114 if (nghttp2_session_server_new(&ptr, callbacks.get(), nullptr) != 0)
115 {
Ed Tanous62598e32023-07-17 17:06:25 -0700116 BMCWEB_LOG_ERROR("nghttp2_session_server_new failed");
Ed Tanousfca2cbe2021-01-28 14:49:59 -0800117 return;
118 }
119 }
120
121 ~nghttp2_session()
122 {
123 nghttp2_session_del(ptr);
124 }
125
126 // explicitly uncopyable
127 nghttp2_session(const nghttp2_session&) = delete;
128 nghttp2_session& operator=(const nghttp2_session&) = delete;
129
130 nghttp2_session(nghttp2_session&& other) noexcept : ptr(other.ptr)
131 {
132 other.ptr = nullptr;
133 }
134
135 nghttp2_session& operator=(nghttp2_session&& other) noexcept = delete;
136
137 int submitSettings(std::span<nghttp2_settings_entry> iv)
138 {
139 return nghttp2_submit_settings(ptr, NGHTTP2_FLAG_NONE, iv.data(),
140 iv.size());
141 }
142 void setUserData(void* object)
143 {
144 nghttp2_session_set_user_data(ptr, object);
145 }
146
147 ssize_t memRecv(std::span<const uint8_t> buffer)
148 {
149 return nghttp2_session_mem_recv(ptr, buffer.data(), buffer.size());
150 }
151
Ed Tanousd0882182024-01-26 23:45:25 -0800152 std::span<const uint8_t> memSend()
Ed Tanousfca2cbe2021-01-28 14:49:59 -0800153 {
Ed Tanousd0882182024-01-26 23:45:25 -0800154 const uint8_t* bytes = nullptr;
155 ssize_t size = nghttp2_session_mem_send(ptr, &bytes);
156 return {bytes, static_cast<size_t>(size)};
Ed Tanousfca2cbe2021-01-28 14:49:59 -0800157 }
158
159 int submitResponse(int32_t streamId, std::span<const nghttp2_nv> headers,
160 const nghttp2_data_provider* dataPrd)
161 {
162 return nghttp2_submit_response(ptr, streamId, headers.data(),
163 headers.size(), dataPrd);
164 }
165
166 private:
167 nghttp2_session* ptr = nullptr;
168};
Ed Tanous52dd6932024-01-29 08:34:59 -0800169
Ed Tanousa93163a2024-03-25 11:20:18 -0700170struct nghttp2_hd_inflater_ex
Ed Tanous52dd6932024-01-29 08:34:59 -0800171{
172 nghttp2_hd_inflater* ptr = nullptr;
173
174 public:
Ed Tanousa93163a2024-03-25 11:20:18 -0700175 nghttp2_hd_inflater_ex()
Ed Tanous52dd6932024-01-29 08:34:59 -0800176 {
177 if (nghttp2_hd_inflate_new(&ptr) != 0)
178 {
179 BMCWEB_LOG_ERROR("nghttp2_hd_inflater_new failed");
180 }
181 }
182
183 ssize_t hd2(nghttp2_nv* nvOut, int* inflateFlags, const uint8_t* in,
184 size_t inlen, int inFinal)
185 {
186 return nghttp2_hd_inflate_hd2(ptr, nvOut, inflateFlags, in, inlen,
187 inFinal);
188 }
189
190 int endHeaders()
191 {
192 return nghttp2_hd_inflate_end_headers(ptr);
193 }
194
Ed Tanousa93163a2024-03-25 11:20:18 -0700195 nghttp2_hd_inflater_ex(const nghttp2_hd_inflater_ex&) = delete;
196 nghttp2_hd_inflater_ex& operator=(const nghttp2_hd_inflater_ex&) = delete;
197 nghttp2_hd_inflater_ex& operator=(nghttp2_hd_inflater_ex&&) = delete;
198 nghttp2_hd_inflater_ex(nghttp2_hd_inflater_ex&& other) = delete;
Ed Tanous52dd6932024-01-29 08:34:59 -0800199
Ed Tanousa93163a2024-03-25 11:20:18 -0700200 ~nghttp2_hd_inflater_ex()
Ed Tanous52dd6932024-01-29 08:34:59 -0800201 {
202 if (ptr != nullptr)
203 {
204 nghttp2_hd_inflate_del(ptr);
205 }
206 }
207};
Ed Tanousa93163a2024-03-25 11:20:18 -0700208// NOLINTEND(readability-identifier-naming,
209// readability-make-member-function-const)