• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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