1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 use std::collections::hash_map::Entry;
15 use std::collections::HashMap;
16
17 use ylong_runtime::iter::parallel::ParSplit;
18
19 use crate::h3::error::CommonError::{BufferTooShort, InternalError};
20 use crate::h3::error::DecodeError::UnexpectedFrame;
21 use crate::h3::error::EncodeError::{
22 NoCurrentFrame, RepeatSetFrame, UnknownFrameType, WrongTypeFrame,
23 };
24 use crate::h3::error::{DecodeError, EncodeError, H3Error};
25 use crate::h3::frame::{Headers, Payload};
26 use crate::h3::octets::{ReadableBytes, WritableBytes};
27 use crate::h3::qpack::encoder::EncodeMessage;
28 use crate::h3::qpack::error::{ErrorCode, QpackError};
29 use crate::h3::qpack::table::DynamicTable;
30 use crate::h3::qpack::{DecoderInst, QpackEncoder};
31 use crate::h3::EncodeError::TooManySettings;
32 use crate::h3::{frame, is_bidirectional, octets, Frame};
33
34 #[derive(PartialEq, Debug)]
35 enum FrameEncoderState {
36 // The initial state for the frame encoder.
37 Idle,
38 FrameComplete,
39 // Header Frame
40 EncodingHeadersFrame,
41 EncodingHeadersPayload,
42 // Data Frame
43 EncodingDataFrame,
44 EncodingDataPayload,
45 // CancelPush Frame
46 EncodingCancelPushFrame,
47 // Settings Frame
48 EncodingSettingsFrame,
49 EncodingSettingsPayload,
50 // Goaway Frame
51 EncodingGoawayFrame,
52 // MaxPushId Frame
53 EncodingMaxPushIdFrame,
54 }
55
56 struct EncodedH3Stream {
57 stream_id: u64,
58 headers_message: Option<EncHeaders>,
59 current_frame: Option<Frame>,
60 state: FrameEncoderState,
61 payload_offset: usize,
62 }
63
64 pub(crate) struct EncHeaders {
65 message: EncodeMessage,
66 repr_offset: usize,
67 inst_offset: usize,
68 }
69
70 /// HTTP3 frame encoder, which serializes a Frame into a byte stream in the
71 /// http3 protocol.
72 ///
73 /// # Examples
74 ///
75 /// ```
76 /// use ylong_http::h3::{Data, Frame, FrameEncoder, Payload};
77 ///
78 /// let mut encoder = FrameEncoder::default();
79 /// let data_frame = Frame::new(
80 /// 0,
81 /// Payload::Data(Data::new(vec![b'h', b'e', b'l', b'l', b'o'])),
82 /// );
83 /// encoder.set_frame(0, data_frame).unwrap();
84 /// let mut res = [0u8; 1024];
85 /// let mut ins = [0u8; 1024];
86 /// let message = encoder.encode(0, &mut res, &mut ins).unwrap();
87 /// ```
88 #[derive(Default)]
89 pub struct FrameEncoder {
90 qpack_encoder: QpackEncoder,
91 streams: HashMap<u64, EncodedH3Stream>,
92 }
93
94 pub struct EncodedSize {
95 frame_size: usize,
96 inst_size: usize,
97 }
98
99 impl FrameEncoder {
100 /// Sets the maximum dynamic table capacity,
101 /// which must not exceed the SETTINGS_QPACK_MAX_TABLE_CAPACITY sent by the
102 /// peer Decoder.
set_max_table_capacity(&mut self, max_cap: usize) -> Result<(), H3Error>103 pub fn set_max_table_capacity(&mut self, max_cap: usize) -> Result<(), H3Error> {
104 self.qpack_encoder
105 .set_max_table_capacity(max_cap)
106 .map_err(|e| EncodeError::QpackError(e).into())
107 }
108
109 /// Sets the SETTINGS_QPACK_BLOCKED_STREAMS sent by the peer Decoder.
set_max_blocked_stream_size(&mut self, max_blocked: usize)110 pub fn set_max_blocked_stream_size(&mut self, max_blocked: usize) {
111 self.qpack_encoder.set_max_blocked_stream_size(max_blocked)
112 }
113
114 /// Sets the current frame to be encoded by the `FrameEncoder`. The state of
115 /// the encoder is updated based on the payload type of the frame.
set_frame(&mut self, stream_id: u64, frame: Frame) -> Result<(), H3Error>116 pub fn set_frame(&mut self, stream_id: u64, frame: Frame) -> Result<(), H3Error> {
117 let stream = self
118 .streams
119 .entry(stream_id)
120 .or_insert(EncodedH3Stream::new(stream_id));
121
122 match stream.state {
123 FrameEncoderState::Idle | FrameEncoderState::FrameComplete => {}
124 _ => return Err(RepeatSetFrame.into()),
125 }
126 stream.current_frame = Some(frame);
127 // set frame state
128 if let Some(ref frame) = stream.current_frame {
129 match *frame.frame_type() {
130 frame::HEADERS_FRAME_TYPE => {
131 if let Payload::Headers(h) = frame.payload() {
132 self.qpack_encoder.set_parts(h.get_part());
133 stream.state = FrameEncoderState::EncodingHeadersFrame;
134 }
135 }
136 frame::DATA_FRAME_TYPE => stream.state = FrameEncoderState::EncodingDataFrame,
137 frame::CANCEL_PUSH_FRAME_TYPE => {
138 stream.state = FrameEncoderState::EncodingCancelPushFrame
139 }
140 frame::SETTINGS_FRAME_TYPE => {
141 stream.state = FrameEncoderState::EncodingSettingsFrame
142 }
143 frame::GOAWAY_FRAME_TYPE => stream.state = FrameEncoderState::EncodingGoawayFrame,
144 frame::MAX_PUSH_ID_FRAME_TYPE => {
145 stream.state = FrameEncoderState::EncodingMaxPushIdFrame
146 }
147 _ => {
148 return Err(UnknownFrameType.into());
149 }
150 };
151 }
152 Ok(())
153 }
154
155 /// Decode the instructions sent by the peer decoder stream.
decode_remote_inst(&mut self, buf: &[u8]) -> Result<(), H3Error>156 pub fn decode_remote_inst(&mut self, buf: &[u8]) -> Result<(), H3Error> {
157 self.qpack_encoder
158 .decode_ins(buf)
159 .map_err(|e| H3Error::Decode(DecodeError::QpackError(e)))
160 }
161
162 /// Serializes a Frame into a byte stream in the http3 protocol.
163 ///
164 /// # Examples
165 ///
166 /// ```
167 /// use ylong_http::h3::{Data, Frame, FrameEncoder, Payload};
168 ///
169 /// let mut encoder = FrameEncoder::default();
170 /// let data_frame = Frame::new(
171 /// 0,
172 /// Payload::Data(Data::new(vec![b'h', b'e', b'l', b'l', b'o'])),
173 /// );
174 /// encoder.set_frame(0, data_frame).unwrap();
175 /// let mut res = [0u8; 1024];
176 /// let mut ins = [0u8; 1024];
177 /// let message = encoder.encode(0, &mut res, &mut ins).unwrap();
178 /// ```
encode( &mut self, stream_id: u64, frame_buf: &mut [u8], inst_buf: &mut [u8], ) -> Result<(usize, usize), H3Error>179 pub fn encode(
180 &mut self,
181 stream_id: u64,
182 frame_buf: &mut [u8],
183 inst_buf: &mut [u8],
184 ) -> Result<(usize, usize), H3Error> {
185 if frame_buf.len() < 1024 {
186 return Err(BufferTooShort.into());
187 }
188 let (mut frame_bytes, inst_bytes) = (0, 0);
189
190 let stream = self.streams.get_mut(&stream_id).ok_or(InternalError)?;
191 while frame_bytes < frame_buf.len() {
192 match stream.state {
193 FrameEncoderState::Idle | FrameEncoderState::FrameComplete => {
194 break;
195 }
196 FrameEncoderState::EncodingHeadersFrame => {
197 let frame_type = stream.encode_frame_type(frame_buf)?;
198 frame_bytes += frame_type;
199 stream.state = FrameEncoderState::EncodingHeadersPayload;
200 }
201 FrameEncoderState::EncodingHeadersPayload => {
202 let (payload, inst) = stream.encode_headers_payload(
203 &mut self.qpack_encoder,
204 &mut frame_buf[frame_bytes..],
205 inst_buf,
206 )?;
207 return Ok((payload + frame_bytes, inst));
208 }
209
210 FrameEncoderState::EncodingDataFrame => {
211 let frame_type = stream.encode_frame_type(frame_buf)?;
212 frame_bytes += frame_type;
213 let len = stream.encode_data_len(&mut frame_buf[frame_bytes..])?;
214 frame_bytes += len;
215 stream.state = FrameEncoderState::EncodingDataPayload;
216 }
217 FrameEncoderState::EncodingDataPayload => {
218 return stream
219 .encode_data_payload(&mut frame_buf[frame_bytes..])
220 .map(|size| (size + frame_bytes, 0));
221 }
222
223 FrameEncoderState::EncodingCancelPushFrame => {
224 let frame_type = stream.encode_frame_type(frame_buf)?;
225 frame_bytes += frame_type;
226 return stream
227 .encode_cancel_push(&mut frame_buf[frame_bytes..])
228 .map(|size| (size + frame_bytes, 0));
229 }
230
231 FrameEncoderState::EncodingSettingsFrame => {
232 let frame_type = stream.encode_frame_type(frame_buf)?;
233 frame_bytes += frame_type;
234 let len = stream.encode_settings_len(&mut frame_buf[frame_bytes..])?;
235 frame_bytes += len;
236 stream.state = FrameEncoderState::EncodingSettingsPayload;
237 }
238 FrameEncoderState::EncodingSettingsPayload => {
239 return stream
240 .encode_settings_payload(&mut frame_buf[frame_bytes..])
241 .map(|size| (size + frame_bytes, 0));
242 }
243
244 FrameEncoderState::EncodingGoawayFrame => {
245 let frame_type = stream.encode_frame_type(frame_buf)?;
246 frame_bytes += frame_type;
247 return stream
248 .encode_goaway(&mut frame_buf[frame_bytes..])
249 .map(|size| (size + frame_bytes, 0));
250 }
251
252 FrameEncoderState::EncodingMaxPushIdFrame => {
253 let frame_type = stream.encode_frame_type(frame_buf)?;
254 frame_bytes += frame_type;
255 return stream
256 .encode_max_push_id(&mut frame_buf[frame_bytes..])
257 .map(|size| (size + frame_bytes, 0));
258 }
259 }
260 }
261 Ok((frame_bytes, inst_bytes))
262 }
263
264 /// Cleans the stream information when the stream normally ends.
finish_stream(&mut self, id: u64) -> Result<(), H3Error>265 pub fn finish_stream(&mut self, id: u64) -> Result<(), H3Error> {
266 if is_bidirectional(id) {
267 self.qpack_encoder
268 .finish_stream(id)
269 .map_err(|e| H3Error::Encode(e.into()))?;
270 }
271 self.streams.remove(&id);
272 Ok(())
273 }
274 }
275
276 impl EncHeaders {
new(message: EncodeMessage) -> Self277 pub(crate) fn new(message: EncodeMessage) -> Self {
278 Self {
279 message,
280 repr_offset: 0,
281 inst_offset: 0,
282 }
283 }
message(&self) -> &EncodeMessage284 pub(crate) fn message(&self) -> &EncodeMessage {
285 &self.message
286 }
287
repr_offset(&self) -> usize288 pub(crate) fn repr_offset(&self) -> usize {
289 self.repr_offset
290 }
291
inst_offset(&self) -> usize292 pub(crate) fn inst_offset(&self) -> usize {
293 self.inst_offset
294 }
295
repr_offset_inc(&mut self, increment: usize)296 pub(crate) fn repr_offset_inc(&mut self, increment: usize) {
297 self.repr_offset += increment
298 }
299
inst_offset_inc(&mut self, increment: usize)300 pub(crate) fn inst_offset_inc(&mut self, increment: usize) {
301 self.inst_offset += increment
302 }
303
remaining_repr(&self) -> usize304 pub(crate) fn remaining_repr(&self) -> usize {
305 self.message.fields().len() - self.repr_offset
306 }
307
remaining_inst(&self) -> usize308 pub(crate) fn remaining_inst(&self) -> usize {
309 self.message.inst().len() - self.inst_offset
310 }
311 }
312
313 impl EncodedSize {
frame_size(&self) -> usize314 pub fn frame_size(&self) -> usize {
315 self.frame_size
316 }
317
inst_size(&self) -> usize318 pub fn inst_size(&self) -> usize {
319 self.inst_size
320 }
321
new(frame_size: usize, inst_size: usize) -> Self322 pub fn new(frame_size: usize, inst_size: usize) -> Self {
323 Self {
324 frame_size,
325 inst_size,
326 }
327 }
328 }
329
330 impl EncodedH3Stream {
new(stream_id: u64) -> Self331 pub(crate) fn new(stream_id: u64) -> Self {
332 Self {
333 stream_id,
334 headers_message: None,
335 current_frame: None,
336 state: FrameEncoderState::Idle,
337 payload_offset: 0,
338 }
339 }
340
encode_settings_payload(&mut self, frame_buf: &mut [u8]) -> Result<usize, H3Error>341 fn encode_settings_payload(&mut self, frame_buf: &mut [u8]) -> Result<usize, H3Error> {
342 let mut written = 0;
343 if let Some(frame) = self.current_frame.as_ref() {
344 if let Payload::Settings(settings) = frame.payload() {
345 // Ensure that it can be completed in a one go.
346 self.state = FrameEncoderState::FrameComplete;
347
348 if let Some(v) = settings.max_fied_section_size() {
349 written += encode_var_integer(
350 frame::SETTING_MAX_FIELD_SECTION_SIZE,
351 &mut frame_buf[written..],
352 )?;
353 written += encode_var_integer(v, &mut frame_buf[written..])?;
354 }
355 if let Some(v) = settings.connect_protocol_enabled() {
356 written += encode_var_integer(
357 frame::SETTING_ENABLE_CONNECT_PROTOCOL,
358 &mut frame_buf[written..],
359 )?;
360 written += encode_var_integer(v, &mut frame_buf[written..])?;
361 }
362 if let Some(v) = settings.qpack_max_table_capacity() {
363 written += encode_var_integer(
364 frame::SETTING_QPACK_MAX_TABLE_CAPACITY,
365 &mut frame_buf[written..],
366 )?;
367 written += encode_var_integer(v, &mut frame_buf[written..])?;
368 }
369 if let Some(v) = settings.qpack_block_stream() {
370 written += encode_var_integer(
371 frame::SETTING_QPACK_BLOCKED_STREAMS,
372 &mut frame_buf[written..],
373 )?;
374 written += encode_var_integer(v, &mut frame_buf[written..])?;
375 }
376 if let Some(v) = settings.h3_datagram() {
377 written +=
378 encode_var_integer(frame::SETTING_H3_DATAGRAM, &mut frame_buf[written..])?;
379 written += encode_var_integer(v, &mut frame_buf[written..])?;
380 }
381 if let Some(v) = settings.additional() {
382 for (key, value) in v.iter() {
383 written += encode_var_integer(*key, &mut frame_buf[written..])?;
384 written += encode_var_integer(*value, &mut frame_buf[written..])?;
385 }
386 }
387 Ok(written)
388 } else {
389 Err(WrongTypeFrame.into())
390 }
391 } else {
392 Err(NoCurrentFrame.into())
393 }
394 }
395
encode_headers_repr_and_inst( &mut self, frame_buf: &mut [u8], inst_buf: &mut [u8], ) -> Result<(usize, usize), H3Error>396 fn encode_headers_repr_and_inst(
397 &mut self,
398 frame_buf: &mut [u8],
399 inst_buf: &mut [u8],
400 ) -> Result<(usize, usize), H3Error> {
401 let repr_writen = self.encode_headers_repr(frame_buf);
402 let inst_writen = self.encode_qpack_inst(inst_buf);
403 if let Some(ref message) = self.headers_message {
404 if message.remaining_repr() == 0 && message.remaining_inst() == 0 {
405 self.state = FrameEncoderState::FrameComplete;
406 self.headers_message = None;
407 }
408 }
409 Ok((repr_writen, inst_writen))
410 }
411
encode_headers_with_qpack( &mut self, qpack_encoder: &mut QpackEncoder, frame_buf: &mut [u8], inst_buf: &mut [u8], ) -> Result<(usize, usize), H3Error>412 fn encode_headers_with_qpack(
413 &mut self,
414 qpack_encoder: &mut QpackEncoder,
415 frame_buf: &mut [u8],
416 inst_buf: &mut [u8],
417 ) -> Result<(usize, usize), H3Error> {
418 if self.headers_message.is_none() {
419 let message = qpack_encoder.encode(self.stream_id);
420 let payload_size = message.fields().len();
421 self.headers_message = Some(EncHeaders::new(message));
422 // encode headers frame payload length
423 let encoded_payload_size = encode_var_integer(payload_size as u64, frame_buf)?;
424 let (frame_size, inst_size) = self
425 .encode_headers_repr_and_inst(&mut frame_buf[encoded_payload_size..], inst_buf)?;
426 Ok((frame_size + encoded_payload_size, inst_size))
427 } else {
428 self.encode_headers_repr_and_inst(frame_buf, inst_buf)
429 }
430 }
431
encode_headers_repr(&mut self, frame_buf: &mut [u8]) -> usize432 fn encode_headers_repr(&mut self, frame_buf: &mut [u8]) -> usize {
433 if let Some(mut enc_headers) = self.headers_message.take() {
434 let mut written = 0;
435 let repr_size = enc_headers.remaining_repr();
436 let cap = frame_buf.len();
437 if cap >= repr_size {
438 frame_buf[..repr_size].copy_from_slice(
439 &enc_headers.message().fields().as_slice()[enc_headers.repr_offset()..],
440 );
441 written += repr_size;
442 // finish encode headers
443 enc_headers.repr_offset_inc(repr_size);
444 } else {
445 frame_buf.copy_from_slice(
446 &enc_headers.message().fields().as_slice()
447 [enc_headers.repr_offset()..enc_headers.repr_offset() + cap],
448 );
449 written += cap;
450 enc_headers.repr_offset_inc(cap);
451 }
452 self.headers_message = Some(enc_headers);
453 return written;
454 }
455 0
456 }
457
encode_qpack_inst(&mut self, inst_buf: &mut [u8]) -> usize458 fn encode_qpack_inst(&mut self, inst_buf: &mut [u8]) -> usize {
459 if let Some(mut enc_headers) = self.headers_message.take() {
460 let mut written = 0;
461 let inst_size = enc_headers.remaining_inst();
462 let cap = inst_buf.len();
463 if cap >= inst_size {
464 inst_buf[..inst_size].copy_from_slice(
465 &enc_headers.message().inst().as_slice()[enc_headers.inst_offset()..],
466 );
467 written += inst_size;
468 // finish encode headers
469 enc_headers.inst_offset_inc(inst_size);
470 } else {
471 inst_buf.copy_from_slice(
472 &enc_headers.message().inst().as_slice()
473 [enc_headers.inst_offset()..enc_headers.inst_offset() + cap],
474 );
475 written += cap;
476 enc_headers.inst_offset_inc(cap);
477 }
478 self.headers_message = Some(enc_headers);
479 return written;
480 }
481 0
482 }
483
encode_frame_type(&self, frame_buf: &mut [u8]) -> Result<usize, H3Error>484 fn encode_frame_type(&self, frame_buf: &mut [u8]) -> Result<usize, H3Error> {
485 if let Some(frame) = self.current_frame.as_ref() {
486 encode_var_integer(*frame.frame_type(), frame_buf)
487 } else {
488 Err(NoCurrentFrame.into())
489 }
490 }
491
encode_data_len(&self, frame_buf: &mut [u8]) -> Result<usize, H3Error>492 fn encode_data_len(&self, frame_buf: &mut [u8]) -> Result<usize, H3Error> {
493 if let Some(frame) = self.current_frame.as_ref() {
494 if let Payload::Data(d) = frame.payload() {
495 encode_var_integer((*d).data().len() as u64, frame_buf)
496 } else {
497 Err(WrongTypeFrame.into())
498 }
499 } else {
500 Err(NoCurrentFrame.into())
501 }
502 }
503
encode_cancel_push(&mut self, frame_buf: &mut [u8]) -> Result<usize, H3Error>504 fn encode_cancel_push(&mut self, frame_buf: &mut [u8]) -> Result<usize, H3Error> {
505 let frame = self
506 .current_frame
507 .as_ref()
508 .ok_or(H3Error::Encode(NoCurrentFrame))?;
509 if let Payload::CancelPush(push) = frame.payload() {
510 let size =
511 encode_var_integer(octets::varint_len(*push.get_push_id()) as u64, frame_buf)?;
512 // Ensure that it can be completed in a one go.
513 self.state = FrameEncoderState::FrameComplete;
514 encode_var_integer(*push.get_push_id(), &mut frame_buf[size..])
515 } else {
516 Err(WrongTypeFrame.into())
517 }
518 }
519
encode_goaway(&mut self, frame_buf: &mut [u8]) -> Result<usize, H3Error>520 fn encode_goaway(&mut self, frame_buf: &mut [u8]) -> Result<usize, H3Error> {
521 if let Some(frame) = self.current_frame.as_ref() {
522 if let Payload::Goaway(away) = frame.payload() {
523 let size =
524 encode_var_integer(octets::varint_len(*away.get_id()) as u64, frame_buf)?;
525 // Ensure that it can be completed in a one go.
526 self.state = FrameEncoderState::FrameComplete;
527
528 encode_var_integer(*away.get_id(), &mut frame_buf[size..])
529 } else {
530 Err(WrongTypeFrame.into())
531 }
532 } else {
533 Err(NoCurrentFrame.into())
534 }
535 }
536
encode_max_push_id(&mut self, frame_buf: &mut [u8]) -> Result<usize, H3Error>537 fn encode_max_push_id(&mut self, frame_buf: &mut [u8]) -> Result<usize, H3Error> {
538 if let Some(frame) = self.current_frame.as_ref() {
539 if let Payload::MaxPushId(push) = frame.payload() {
540 let size =
541 encode_var_integer(octets::varint_len(*push.get_id()) as u64, frame_buf)?;
542 // Ensure that it can be completed in a one go.
543 self.state = FrameEncoderState::FrameComplete;
544
545 encode_var_integer(*push.get_id(), &mut frame_buf[size..])
546 } else {
547 Err(WrongTypeFrame.into())
548 }
549 } else {
550 Err(NoCurrentFrame.into())
551 }
552 }
553
encode_settings_len(&self, frame_buf: &mut [u8]) -> Result<usize, H3Error>554 fn encode_settings_len(&self, frame_buf: &mut [u8]) -> Result<usize, H3Error> {
555 let mut written = 0;
556 if let Some(frame) = self.current_frame.as_ref() {
557 if let Payload::Settings(settings) = frame.payload() {
558 if let Some(v) = settings.max_fied_section_size() {
559 written += octets::varint_len(frame::SETTING_MAX_FIELD_SECTION_SIZE);
560 written += octets::varint_len(v);
561 }
562 if let Some(v) = settings.connect_protocol_enabled() {
563 written += octets::varint_len(frame::SETTING_ENABLE_CONNECT_PROTOCOL);
564 written += octets::varint_len(v);
565 }
566 if let Some(v) = settings.qpack_max_table_capacity() {
567 written += octets::varint_len(frame::SETTING_QPACK_MAX_TABLE_CAPACITY);
568 written += octets::varint_len(v);
569 }
570 if let Some(v) = settings.qpack_block_stream() {
571 written += octets::varint_len(frame::SETTING_QPACK_BLOCKED_STREAMS);
572 written += octets::varint_len(v);
573 }
574 if let Some(v) = settings.h3_datagram() {
575 written += octets::varint_len(frame::SETTING_H3_DATAGRAM);
576 written += octets::varint_len(v);
577 }
578 if let Some(v) = settings.additional() {
579 // ensure frame buf is enough capacity.
580 if v.len() > 50 {
581 return Err(TooManySettings.into());
582 }
583 for (key, value) in v.iter() {
584 written += octets::varint_len(*key);
585 written += octets::varint_len(*value);
586 }
587 }
588 let var_written = encode_var_integer(written as u64, frame_buf)?;
589 Ok(var_written)
590 } else {
591 Err(WrongTypeFrame.into())
592 }
593 } else {
594 Err(NoCurrentFrame.into())
595 }
596 }
597
encode_headers_payload( &mut self, qpack_encoder: &mut QpackEncoder, frame_buf: &mut [u8], inst_buf: &mut [u8], ) -> Result<(usize, usize), H3Error>598 fn encode_headers_payload(
599 &mut self,
600 qpack_encoder: &mut QpackEncoder,
601 frame_buf: &mut [u8],
602 inst_buf: &mut [u8],
603 ) -> Result<(usize, usize), H3Error> {
604 if let Some(frame) = self.current_frame.as_ref() {
605 if let Payload::Headers(_headers) = frame.payload() {
606 self.encode_headers_with_qpack(qpack_encoder, frame_buf, inst_buf)
607 } else {
608 Err(WrongTypeFrame.into())
609 }
610 } else {
611 Err(NoCurrentFrame.into())
612 }
613 }
614
encode_data_payload(&mut self, frame_buf: &mut [u8]) -> Result<usize, H3Error>615 fn encode_data_payload(&mut self, frame_buf: &mut [u8]) -> Result<usize, H3Error> {
616 if let Some(frame) = self.current_frame.as_ref() {
617 if let Payload::Data(d) = frame.payload() {
618 let data = d.data();
619 let buf_size = frame_buf.len();
620 let remaining = data.len() - self.payload_offset;
621 if buf_size >= remaining {
622 frame_buf[..remaining].copy_from_slice(&data.as_slice()[self.payload_offset..]);
623 self.payload_offset = 0;
624 self.state = FrameEncoderState::FrameComplete;
625 Ok(remaining)
626 } else {
627 frame_buf.copy_from_slice(
628 &data.as_slice()[self.payload_offset..self.payload_offset + buf_size],
629 );
630 self.payload_offset += buf_size;
631 Ok(buf_size)
632 }
633 } else {
634 Err(WrongTypeFrame.into())
635 }
636 } else {
637 Err(NoCurrentFrame.into())
638 }
639 }
640 }
641
encode_var_integer(src: u64, frame_buf: &mut [u8]) -> Result<usize, H3Error>642 fn encode_var_integer(src: u64, frame_buf: &mut [u8]) -> Result<usize, H3Error> {
643 let mut writable_buf = WritableBytes::from(frame_buf);
644 writable_buf.write_varint(src)?;
645 let size = writable_buf.index();
646 Ok(size)
647 }
648
649 #[cfg(test)]
650 mod h3_encoder {
651 use crate::h3::qpack::table::NameField;
652 use crate::h3::{Data, Frame, FrameEncoder, Headers, Parts, Payload, PseudoHeaders, Settings};
653
654 /// UT test cases for `FrameEncoder` encoding `Settings` frame.
655 ///
656 /// # Brief
657 /// 1. Creates a `FrameEncoder`.
658 /// 2. Creates a `Frame` with `Payload::Settings`.
659 /// 3. Sets the frame for the encoder.
660 /// 4. Encodes the frame with request stream id.
661 /// 5. Checks whether the result is correct.
662 #[test]
ut_encoder_request_stream_settings()663 fn ut_encoder_request_stream_settings() {
664 let mut encoder = FrameEncoder::default();
665 let setting = Settings::default();
666 let setting = Frame::new(0x4, Payload::Settings(setting));
667 encoder.set_frame(1, setting).unwrap();
668 let mut data_buf = [0u8; 1024];
669 let mut inst_buf = [0u8; 1024];
670 let res = encoder.encode(0, &mut data_buf, &mut inst_buf);
671 assert!(res.is_err());
672 }
673
674 /// UT test cases for `FrameEncoder` encoding `Settings` frame.
675 ///
676 /// # Brief
677 /// 1. Creates a `FrameEncoder`.
678 /// 2. Creates a `Frame` with `Payload::Settings`.
679 /// 3. Sets the frame for the encoder.
680 /// 4. Encodes the frame with control stream id.
681 /// 5. Checks whether the result is correct.
682 #[test]
ut_encoder_control_stream_settings()683 fn ut_encoder_control_stream_settings() {
684 let mut encoder = FrameEncoder::default();
685 let mut setting = Settings::default();
686 setting.set_max_field_section_size(1024);
687 setting.set_qpack_block_stream(50);
688 setting.set_qpack_max_table_capacity(1024);
689 let setting = Frame::new(0x4, Payload::Settings(setting));
690 encoder.set_frame(1, setting).unwrap();
691 let mut data_buf = [0u8; 1024];
692 let mut inst_buf = [0u8; 1024];
693
694 let (data_idx, inst_idx) = encoder.encode(1, &mut data_buf, &mut inst_buf).unwrap();
695 assert_eq!([4, 8, 6, 68, 0, 1, 68, 0, 7, 50], data_buf[..data_idx]);
696 assert_eq!(inst_idx, 0);
697 }
698
699 /// UT test cases for `FrameEncoder` encoding `Headers` frame.
700 ///
701 /// # Brief
702 /// 1. Creates a `FrameEncoder`.
703 /// 2. Creates a `Frame` with `Payload::Headers`.
704 /// 3. Sets the frame for the encoder.
705 /// 4. Encodes the frame with request stream id.
706 /// 5. Checks whether the result is correct.
707 #[test]
ut_encoder_request_stream_header()708 fn ut_encoder_request_stream_header() {
709 let mut encoder = FrameEncoder::default();
710 encoder.set_max_table_capacity(400).unwrap();
711 let mut parts = Parts::new();
712 parts.update(
713 NameField::Other("test-header".to_string()),
714 "test-header".to_string(),
715 );
716 parts.update(NameField::Method, "GET".to_string());
717 parts.update(NameField::Scheme, "HTTPS".to_string());
718 parts.update(NameField::Authority, "www.example.com".to_string());
719 let headers = Headers::new(parts);
720 let header = Frame::new(1, Payload::Headers(headers));
721 encoder.set_frame(0, header).unwrap();
722 let mut data_buf = [0u8; 1024];
723 let mut inst_buf = [0u8; 1024];
724
725 let (data_idx, inst_idx) = encoder.encode(0, &mut data_buf, &mut inst_buf).unwrap();
726 assert_eq!(
727 data_buf[..data_idx],
728 [
729 1, 43, 0, 0, 209, 95, 7, 133, 199, 191, 126, 189, 223, 80, 140, 241, 227, 194, 229,
730 242, 58, 107, 160, 171, 144, 244, 255, 43, 73, 80, 149, 167, 40, 228, 45, 159, 136,
731 73, 80, 149, 167, 40, 228, 45, 159
732 ]
733 );
734 assert_eq!(&inst_buf[..inst_idx], [63, 241, 2]);
735 }
736
737 /// UT test cases for `FrameEncoder` encoding `Data` frame.
738 ///
739 /// # Brief
740 /// 1. Creates a `FrameEncoder`.
741 /// 2. Creates a `Frame` with `Payload::Data`.
742 /// 3. Sets the frame for the encoder.
743 /// 4. Encodes the frame with request stream id.
744 /// 5. Checks whether the result is correct.
745 #[test]
ut_encoder_request_stream_data()746 fn ut_encoder_request_stream_data() {
747 let mut encoder = FrameEncoder::default();
748 let data_body = Data::new(Vec::from("hello"));
749 let data = Frame::new(0, Payload::Data(data_body));
750
751 encoder.set_frame(0, data).unwrap();
752 let mut data_buf = [0u8; 1024];
753 let mut inst_buf = [0u8; 1024];
754 let (data_idx, inst_idx) = encoder.encode(0, &mut data_buf, &mut inst_buf).unwrap();
755 assert_eq!([0, 5, 104, 101, 108, 108, 111], data_buf[..data_idx]);
756 assert_eq!(inst_idx, 0)
757 }
758 }
759