Skip to main content

br_web_server/
stream.rs

1use crate::request::Request;
2use crate::websocket::{CloseCode, ErrorCode, Message, MessageMode, MessageType};
3use crate::{HttpError, Method, Uri};
4use hpack::Decoder;
5use log::{info, warn};
6use rustls::{ClientConnection, ServerConnection, StreamOwned};
7use std::io::{ErrorKind, Read, Write};
8use std::net::TcpStream;
9use std::sync::{Arc, Mutex};
10use std::thread;
11use std::time::Duration;
12
13const IO_BUF_SIZE: usize = 1024 * 1024;
14const IO_SMALL_BUF_SIZE: usize = 1024 * 64;
15const WS_READ_TIMEOUT_MS: u64 = 100;
16
17#[derive(Debug, Clone)]
18pub enum Scheme {
19    Http(Arc<Mutex<TcpStream>>),
20    Https(Arc<Mutex<StreamOwned<ServerConnection, TcpStream>>>),
21}
22
23/// WebSocket 读取端 - 独立拥有读取半连接,无锁竞争
24pub struct SchemeReader {
25    inner: SchemeReaderInner,
26    pending: Vec<u8>,
27}
28
29#[allow(dead_code)]
30enum SchemeReaderInner {
31    Http(TcpStream),
32    Https(Box<rustls::StreamOwned<ServerConnection, TcpStream>>),
33}
34
35/// WebSocket 写入端 - 独立拥有写入半连接,无锁竞争
36pub struct SchemeWriter {
37    inner: SchemeWriterInner,
38}
39
40#[allow(dead_code)]
41enum SchemeWriterInner {
42    Http(TcpStream),
43    Https(Box<rustls::StreamOwned<ServerConnection, TcpStream>>),
44}
45
46impl Scheme {
47    pub fn split_for_websocket(
48        scheme: &Arc<Mutex<Scheme>>,
49    ) -> Result<(SchemeReader, SchemeWriter), HttpError> {
50        let guard = scheme
51            .lock()
52            .map_err(|e| HttpError::new(500, &format!("lock poisoned: {}", e)))?;
53        match &*guard {
54            Scheme::Http(stream) => {
55                let inner_guard = stream
56                    .lock()
57                    .map_err(|e| HttpError::new(500, &format!("lock poisoned: {}", e)))?;
58                let read_stream = inner_guard.try_clone().map_err(|e| {
59                    HttpError::new(500, &format!("clone read stream failed: {}", e))
60                })?;
61                let write_stream = inner_guard.try_clone().map_err(|e| {
62                    HttpError::new(500, &format!("clone write stream failed: {}", e))
63                })?;
64                Ok((
65                    SchemeReader {
66                        inner: SchemeReaderInner::Http(read_stream),
67                        pending: vec![],
68                    },
69                    SchemeWriter {
70                        inner: SchemeWriterInner::Http(write_stream),
71                    },
72                ))
73            }
74            Scheme::Https(_) => Err(HttpError::new(
75                500,
76                "HTTPS split not supported, use shared mode",
77            )),
78        }
79    }
80}
81
82impl SchemeReader {
83    pub fn read_ws_data(
84        &mut self,
85        deflate: &crate::websocket::DeflateConfig,
86    ) -> Result<Message, HttpError> {
87        // 先检查 pending 缓冲区是否有完整帧
88        if !self.pending.is_empty() {
89            let message = Message::parse_message(&mut self.pending, deflate);
90            match message.message_type {
91                MessageType::TimeOut => {} // 数据不完整,继续读取
92                _ => return Ok(message),
93            }
94        }
95
96        let mut buffer = vec![0u8; IO_BUF_SIZE];
97
98        let res = match &mut self.inner {
99            SchemeReaderInner::Http(stream) => {
100                stream
101                    .set_read_timeout(Some(Duration::from_millis(WS_READ_TIMEOUT_MS)))
102                    .ok();
103                let result = stream.read(&mut buffer);
104                stream.set_read_timeout(None).ok();
105                result
106            }
107            SchemeReaderInner::Https(stream) => {
108                stream
109                    .get_mut()
110                    .set_read_timeout(Some(Duration::from_millis(WS_READ_TIMEOUT_MS)))
111                    .ok();
112                let result = stream.read(&mut buffer);
113                stream.get_mut().set_read_timeout(None).ok();
114                result
115            }
116        };
117
118        match res {
119            Ok(0) => Ok(Message {
120                mode: MessageMode::Client,
121                message_type: MessageType::Close,
122                payload: vec![],
123                text: CloseCode::GoingAway.str(),
124                close: CloseCode::GoingAway,
125                error: ErrorCode::None,
126            }),
127            Ok(n) => {
128                self.pending.extend_from_slice(&buffer[..n]);
129                let start = std::time::Instant::now();
130                let total_timeout = Duration::from_secs(30);
131
132                loop {
133                    if start.elapsed() > total_timeout {
134                        log::warn!("等待 WebSocket 完整帧超时 (30s),关闭连接");
135                        return Ok(Message {
136                            mode: MessageMode::Client,
137                            message_type: MessageType::Close,
138                            payload: vec![],
139                            text: "等待完整帧超时".to_string(),
140                            close: CloseCode::ProtocolError,
141                            error: ErrorCode::TimeOut,
142                        });
143                    }
144
145                    let message = Message::parse_message(&mut self.pending, deflate);
146
147                    match message.message_type {
148                        MessageType::TimeOut => {
149                            let mut more_buffer = vec![0u8; IO_SMALL_BUF_SIZE];
150                            let more_res = match &mut self.inner {
151                                SchemeReaderInner::Http(stream) => {
152                                    stream
153                                        .set_read_timeout(Some(Duration::from_millis(
154                                            WS_READ_TIMEOUT_MS,
155                                        )))
156                                        .ok();
157                                    let result = stream.read(&mut more_buffer);
158                                    stream.set_read_timeout(None).ok();
159                                    result
160                                }
161                                SchemeReaderInner::Https(stream) => {
162                                    stream
163                                        .get_mut()
164                                        .set_read_timeout(Some(Duration::from_millis(
165                                            WS_READ_TIMEOUT_MS,
166                                        )))
167                                        .ok();
168                                    let result = stream.read(&mut more_buffer);
169                                    stream.get_mut().set_read_timeout(None).ok();
170                                    result
171                                }
172                            };
173                            match more_res {
174                                Ok(0) => {
175                                    return Ok(Message {
176                                        mode: MessageMode::Client,
177                                        message_type: MessageType::Close,
178                                        payload: vec![],
179                                        text: CloseCode::GoingAway.str(),
180                                        close: CloseCode::GoingAway,
181                                        error: ErrorCode::None,
182                                    });
183                                }
184                                Ok(m) => {
185                                    self.pending.extend_from_slice(&more_buffer[..m]);
186                                    continue;
187                                }
188                                Err(ref e)
189                                    if e.kind() == ErrorKind::WouldBlock
190                                        || e.kind() == ErrorKind::TimedOut =>
191                                {
192                                    continue;
193                                }
194                                Err(_) => {
195                                    continue;
196                                }
197                            }
198                        }
199                        _ => return Ok(message),
200                    }
201                }
202            }
203            Err(ref e) if e.kind() == ErrorKind::WouldBlock => Ok(Message {
204                mode: MessageMode::Client,
205                message_type: MessageType::TimeOut,
206                payload: vec![],
207                text: String::new(),
208                close: CloseCode::NormalClosure,
209                error: ErrorCode::TimeOut,
210            }),
211            Err(e) => Ok(Message {
212                mode: MessageMode::Client,
213                message_type: MessageType::Error,
214                payload: vec![],
215                text: e.to_string(),
216                close: CloseCode::Other(1011),
217                error: ErrorCode::Unknown,
218            }),
219        }
220    }
221}
222
223impl SchemeWriter {
224    /// 写入数据
225    pub fn write_all(&mut self, data: &[u8]) -> Result<(), HttpError> {
226        let result = match &mut self.inner {
227            SchemeWriterInner::Http(stream) => stream.write_all(data),
228            SchemeWriterInner::Https(stream) => stream.write_all(data),
229        };
230        match result {
231            Ok(()) => {
232                self.flush()?;
233                Ok(())
234            }
235            Err(e) => Err(HttpError::new(500, format!("write: {}", e).as_str())),
236        }
237    }
238
239    /// 刷新缓冲区
240    pub fn flush(&mut self) -> Result<(), HttpError> {
241        let result = match &mut self.inner {
242            SchemeWriterInner::Http(stream) => stream.flush(),
243            SchemeWriterInner::Https(stream) => stream.flush(),
244        };
245        match result {
246            Ok(()) => Ok(()),
247            Err(e) => Err(HttpError::new(500, format!("flush: {}", e).as_str())),
248        }
249    }
250}
251
252impl Scheme {
253    /// 读取
254    pub fn read(&mut self, data: &mut Vec<u8>) -> Result<(), HttpError> {
255        let mut buf = vec![0u8; IO_BUF_SIZE];
256
257        let mut index = 2;
258        loop {
259            let result = match self {
260                Self::Http(stream) => stream
261                    .lock()
262                    .map_err(|e| HttpError::new(500, &format!("lock poisoned: {}", e)))?
263                    .read(&mut buf),
264                Self::Https(stream) => stream
265                    .lock()
266                    .map_err(|e| HttpError::new(500, &format!("lock poisoned: {}", e)))?
267                    .read(&mut buf),
268            };
269            return match result {
270                Ok(0) => Err(HttpError::new(500, "read: 客户端主动关闭")),
271                Ok(n) => {
272                    data.extend(&buf[..n]);
273                    return Ok(());
274                }
275                Err(ref e) if e.kind() == ErrorKind::Interrupted => {
276                    if !data.is_empty() {
277                        return Ok(());
278                    }
279                    if index > 0 {
280                        index -= 1;
281                        continue;
282                    }
283                    Err(HttpError::new(
284                        500,
285                        format!("read现在没数据可读: {}", e.to_string().as_str()).as_str(),
286                    ))
287                }
288                Err(e) => Err(HttpError::new(
289                    500,
290                    format!("read: {}", e.to_string().as_str()).as_str(),
291                )),
292            };
293        }
294    }
295    /// 指定长度
296    fn read_data(&self, init_data: &mut Vec<u8>, length: usize) -> Result<(), HttpError> {
297        let deadline = std::time::Instant::now() + std::time::Duration::from_secs(30);
298        loop {
299            if init_data.len() >= length {
300                return Ok(());
301            }
302            let mut buf = vec![0u8; IO_BUF_SIZE];
303            let result = match self {
304                Self::Http(stream) => stream
305                    .lock()
306                    .map_err(|e| HttpError::new(500, &format!("lock poisoned: {}", e)))?
307                    .read(&mut buf),
308                Self::Https(stream) => stream
309                    .lock()
310                    .map_err(|e| HttpError::new(500, &format!("lock poisoned: {}", e)))?
311                    .read(&mut buf),
312            };
313            return match result {
314                Ok(0) => Err(HttpError::new(500, "read_data: 客户端主动关闭")),
315                Ok(n) => {
316                    init_data.extend(&buf[..n]);
317                    Ok(())
318                }
319                Err(ref e) if e.kind() == ErrorKind::WouldBlock => {
320                    // ⚠️ 当前无数据可读,稍后再试
321                    if std::time::Instant::now() > deadline {
322                        return Err(HttpError::new(408, "read_data: timeout"));
323                    }
324                    thread::sleep(Duration::from_millis(100));
325                    continue;
326                }
327                Err(e) => Err(HttpError::new(
328                    500,
329                    format!("read_data: {}", e.to_string().as_str()).as_str(),
330                )),
331            };
332        }
333    }
334
335    /// 写入
336    pub fn write(&mut self, data: &[u8]) -> Result<(), HttpError> {
337        let mut off = 0;
338        loop {
339            let result = match self {
340                Self::Http(stream) => stream
341                    .lock()
342                    .map_err(|e| HttpError::new(500, &format!("lock poisoned: {}", e)))?
343                    .write(&data[off..]),
344                Self::Https(stream) => stream
345                    .lock()
346                    .map_err(|e| HttpError::new(500, &format!("lock poisoned: {}", e)))?
347                    .get_mut()
348                    .write(&data[off..]),
349            };
350            match result {
351                Ok(0) => return Err(HttpError::new(500, "write: 客户端主动关闭")),
352                Ok(e) => {
353                    if e != data.len() {
354                        off = e;
355                        continue;
356                    }
357                    self.flush()?;
358                    return Ok(());
359                }
360                Err(ref e)
361                    if e.kind() == ErrorKind::WouldBlock || e.kind() == ErrorKind::Interrupted => {}
362                Err(e) => {
363                    return Err(HttpError::new(
364                        500,
365                        format!("write: {}", e.to_string().as_str()).as_str(),
366                    ))
367                }
368            };
369        }
370    }
371    pub fn write_all(&mut self, data: &[u8]) -> Result<(), HttpError> {
372        let result = match self {
373            Self::Http(stream) => stream
374                .lock()
375                .map_err(|e| HttpError::new(500, &format!("lock poisoned: {}", e)))?
376                .write_all(data),
377            Self::Https(stream) => stream
378                .lock()
379                .map_err(|e| HttpError::new(500, &format!("lock poisoned: {}", e)))?
380                .write_all(data),
381        };
382        match result {
383            Ok(()) => {
384                self.flush()?;
385                Ok(())
386            }
387            Err(e) => Err(HttpError::new(
388                500,
389                format!("write: {}", e.to_string().as_str()).as_str(),
390            )),
391        }
392    }
393
394    pub fn flush(&mut self) -> Result<(), HttpError> {
395        let result = match self {
396            Self::Http(stream) => stream
397                .lock()
398                .map_err(|e| HttpError::new(500, &format!("lock poisoned: {}", e)))?
399                .flush(),
400            Self::Https(stream) => stream
401                .lock()
402                .map_err(|e| HttpError::new(500, &format!("lock poisoned: {}", e)))?
403                .flush(),
404        };
405        match result {
406            Ok(()) => Ok(()),
407            Err(e) => Err(HttpError::new(
408                500,
409                format!("flush: {}", e.to_string().as_str()).as_str(),
410            )),
411        }
412    }
413
414    pub fn read_ws_data(
415        &mut self,
416        deflate: &crate::websocket::DeflateConfig,
417    ) -> Result<Message, HttpError> {
418        let mut response = vec![];
419        let mut buffer = vec![0u8; IO_BUF_SIZE];
420        let res = match self {
421            Self::Http(stream) => {
422                let mut guard = stream
423                    .lock()
424                    .map_err(|e| HttpError::new(500, &format!("lock poisoned: {}", e)))?;
425                guard
426                    .set_read_timeout(Some(std::time::Duration::from_millis(WS_READ_TIMEOUT_MS)))
427                    .ok();
428                let result = guard.read(&mut buffer);
429                guard.set_read_timeout(None).ok();
430                result
431            }
432            Self::Https(ref mut stream) => {
433                let mut guard = stream
434                    .lock()
435                    .map_err(|e| HttpError::new(500, &format!("lock poisoned: {}", e)))?;
436                guard
437                    .get_mut()
438                    .set_read_timeout(Some(std::time::Duration::from_millis(WS_READ_TIMEOUT_MS)))
439                    .ok();
440                let result = guard.read(&mut buffer);
441                guard.get_mut().set_read_timeout(None).ok();
442                result
443            }
444        };
445        match res {
446            Ok(0) => Ok(Message {
447                mode: MessageMode::Client,
448                message_type: MessageType::Close,
449                payload: vec![],
450                text: CloseCode::GoingAway.str(),
451                close: CloseCode::GoingAway,
452                error: ErrorCode::None,
453            }),
454            Ok(n) => {
455                response.extend(buffer[..n].to_vec());
456                let start = std::time::Instant::now();
457                let total_timeout = std::time::Duration::from_secs(30);
458
459                loop {
460                    if start.elapsed() > total_timeout {
461                        log::warn!("等待 WebSocket 完整帧超时 (30s),关闭连接");
462                        return Ok(Message {
463                            mode: MessageMode::Client,
464                            message_type: MessageType::Close,
465                            payload: vec![],
466                            text: "等待完整帧超时".to_string(),
467                            close: CloseCode::ProtocolError,
468                            error: ErrorCode::TimeOut,
469                        });
470                    }
471
472                    let message = Message::parse_message(&mut response, deflate);
473
474                    match message.message_type {
475                        MessageType::TimeOut => {
476                            let mut more_buffer = vec![0u8; IO_SMALL_BUF_SIZE];
477                            let more_res = match self {
478                                Self::Http(stream) => {
479                                    let mut guard = stream.lock().map_err(|e| {
480                                        HttpError::new(500, &format!("lock poisoned: {}", e))
481                                    })?;
482                                    guard
483                                        .set_read_timeout(Some(std::time::Duration::from_millis(
484                                            WS_READ_TIMEOUT_MS,
485                                        )))
486                                        .ok();
487                                    let result = guard.read(&mut more_buffer);
488                                    guard.set_read_timeout(None).ok();
489                                    result
490                                }
491                                Self::Https(ref mut stream) => {
492                                    let mut guard = stream.lock().map_err(|e| {
493                                        HttpError::new(500, &format!("lock poisoned: {}", e))
494                                    })?;
495                                    guard
496                                        .get_mut()
497                                        .set_read_timeout(Some(std::time::Duration::from_millis(
498                                            WS_READ_TIMEOUT_MS,
499                                        )))
500                                        .ok();
501                                    let result = guard.read(&mut more_buffer);
502                                    guard.get_mut().set_read_timeout(None).ok();
503                                    result
504                                }
505                            };
506                            match more_res {
507                                Ok(0) => {
508                                    return Ok(Message {
509                                        mode: MessageMode::Client,
510                                        message_type: MessageType::Close,
511                                        payload: vec![],
512                                        text: CloseCode::GoingAway.str(),
513                                        close: CloseCode::GoingAway,
514                                        error: ErrorCode::None,
515                                    });
516                                }
517                                Ok(m) => {
518                                    response.extend(more_buffer[..m].to_vec());
519                                    continue;
520                                }
521                                Err(ref e)
522                                    if e.kind() == ErrorKind::WouldBlock
523                                        || e.kind() == ErrorKind::TimedOut =>
524                                {
525                                    continue;
526                                }
527                                Err(_) => {
528                                    continue;
529                                }
530                            }
531                        }
532                        _ => return Ok(message),
533                    }
534                }
535            }
536            Err(ref e) if e.kind() == ErrorKind::WouldBlock => Ok(Message {
537                mode: MessageMode::Client,
538                message_type: MessageType::TimeOut,
539                payload: vec![],
540                text: String::new(),
541                close: CloseCode::NormalClosure,
542                error: ErrorCode::TimeOut,
543            }),
544            Err(e) => Ok(Message {
545                mode: MessageMode::Client,
546                message_type: MessageType::Error,
547                payload: vec![],
548                text: e.to_string(),
549                close: CloseCode::Other(1011),
550                error: ErrorCode::Unknown,
551            }),
552        }
553    }
554
555    pub fn client_ip(&mut self) -> String {
556        match self {
557            Self::Http(stream) => match stream.lock() {
558                Ok(guard) => match guard.peer_addr() {
559                    Ok(e) => e.ip().to_string(),
560                    Err(_) => "unknown".to_string(),
561                },
562                Err(_) => "unknown".to_string(),
563            },
564            Self::Https(stream) => stream
565                .lock()
566                .ok()
567                .and_then(|mut guard| guard.get_mut().peer_addr().ok())
568                .map(|a| a.ip().to_string())
569                .unwrap_or_else(|| "unknown".to_string()),
570        }
571    }
572    pub fn server_ip(&mut self) -> String {
573        match self {
574            Self::Http(stream) => stream
575                .lock()
576                .ok()
577                .and_then(|guard| guard.local_addr().ok())
578                .map(|a| a.ip().to_string())
579                .unwrap_or_else(|| "unknown".to_string()),
580            Self::Https(stream) => stream
581                .lock()
582                .ok()
583                .and_then(|mut guard| guard.get_mut().local_addr().ok())
584                .map(|a| a.ip().to_string())
585                .unwrap_or_else(|| "unknown".to_string()),
586        }
587    }
588    /// 读取HTTP2
589    pub fn http2_packet(
590        &mut self,
591        init_data: &mut Vec<u8>,
592    ) -> Result<(Vec<u8>, FrameType, u8, u32), HttpError> {
593        let bytes = init_data;
594        self.read_data(bytes, 9)?;
595        let headers = bytes.drain(..9).collect::<Vec<u8>>();
596        let length =
597            ((headers[0] as u32) << 16) | (u32::from(headers[1]) << 8) | u32::from(headers[2]);
598        let frame_type = headers[3];
599        let flags = headers[4];
600        let stream_id =
601            u32::from_be_bytes([headers[5], headers[6], headers[7], headers[8]]) & 0x7FFF_FFFF;
602        self.read_data(bytes, length as usize)?;
603        let payload = bytes.drain(..length as usize).collect::<Vec<u8>>();
604        Ok((payload, FrameType::from(frame_type), flags, stream_id))
605    }
606    /// 读取HTTP2消息头
607    pub fn http2_handle_header(
608        &mut self,
609        data: &mut Vec<u8>,
610        request: &mut Request,
611    ) -> Result<(), HttpError> {
612        loop {
613            let (payload, frame_type, flags, stream_id) = self.http2_packet(data)?;
614            if request.config.debug {
615                info!("http2_handle_header: frame_type: {frame_type:?} flags: {flags} stream_id: {stream_id} payload: {}", payload.len());
616            }
617            match frame_type {
618                FrameType::Settings => {
619                    let is_ack = flags & 0x01 != 0;
620                    if !is_ack {
621                        self.http2_settings_ack()?;
622                    }
623                }
624                FrameType::WindowUpdate => {
625                    if payload.len() == 4 {
626                        let raw =
627                            u32::from_be_bytes(<[u8; 4]>::try_from(&payload[..4]).map_err(
628                                |_| HttpError::new(400, "invalid WindowUpdate frame data"),
629                            )?);
630                        let increment = raw & 0x7FFF_FFFF; // 屏蔽最高位保留位
631                        if request.config.debug {
632                            info!("WindowUpdate: increment = {} {:?}", increment, payload);
633                        }
634                    } else {
635                        return Err(HttpError::new(
636                            400,
637                            format!("Invalid WindowUpdate frame length: {}", payload.len())
638                                .as_str(),
639                        ));
640                    }
641                }
642                FrameType::Headers => {
643                    let mut decoder = Decoder::new();
644                    let headers = decoder.decode(&payload).map_err(|e| {
645                        HttpError::new(400, &format!("HPACK decode error: {:?}", e))
646                    })?;
647                    if request.config.debug {
648                        println!(
649                            "=================请求头 {:?}=================",
650                            thread::current().id()
651                        );
652                    }
653                    for (name, value) in headers {
654                        let header_name = String::from_utf8_lossy(name.as_slice());
655                        let header_value = String::from_utf8_lossy(value.as_slice());
656                        if request.config.debug {
657                            println!("{header_name}: {header_value}");
658                        }
659                        match header_name.as_ref() {
660                            ":method" => request.method = Method::from(header_value.as_ref()),
661                            ":path" => request.uri = Uri::from(header_value.as_ref()),
662                            ":scheme" => request.set_header("scheme", header_value.as_ref())?,
663                            ":authority" => request.set_header("host", header_value.as_ref())?,
664                            _ => request.set_header(&header_name, &header_value)?,
665                        }
666                    }
667                    if request.config.debug {
668                        println!("====================================================");
669                    }
670                    return Ok(());
671                }
672                _ => {
673                    return Err(HttpError::new(
674                        400,
675                        format!("Invalid {frame_type:?}").as_str(),
676                    ))
677                }
678            }
679        }
680    }
681    /// 读取HTTP2消息体
682    pub fn http2_handle_body(
683        &mut self,
684        data: &mut Vec<u8>,
685        request: Request,
686    ) -> Result<Vec<u8>, HttpError> {
687        let mut body = vec![];
688        loop {
689            let (payload, frame_type, flags, stream_id) = self.http2_packet(data)?;
690            if request.config.debug {
691                info!("http2_handle_body: frame_type: {frame_type:?} flags: {flags} stream_id: {stream_id} data: {}",payload.len());
692            }
693            match frame_type {
694                FrameType::Data => {
695                    body.extend(payload);
696                    if body.len() > request.config.max_body_size {
697                        return Err(HttpError::new(413, "Request body too large"));
698                    }
699                    if flags == 1 {
700                        return Ok(body);
701                    }
702                }
703                FrameType::Headers => {}
704                FrameType::RstStream => {}
705                FrameType::Settings => {
706                    if !payload.is_empty() {
707                        self.http2_send_server_settings()?;
708                    } else {
709                        self.http2_settings_ack()?;
710                    }
711                }
712                FrameType::Ping => {}
713                FrameType::Goaway => {
714                    let text = String::from_utf8_lossy(&payload);
715                    if request.config.debug {
716                        warn!("Goaway: {text}");
717                    }
718                    return Ok(vec![]);
719                }
720                FrameType::WindowUpdate => {
721                    if payload.len() == 4 {
722                        let raw =
723                            u32::from_be_bytes(<[u8; 4]>::try_from(&payload[..4]).map_err(
724                                |_| HttpError::new(400, "invalid WindowUpdate frame data"),
725                            )?);
726                        let increment = raw & 0x7FFF_FFFF; // 屏蔽最高位保留位
727                        if request.config.debug {
728                            info!("WindowUpdate: increment = {} {:?}", increment, payload);
729                        }
730                    } else {
731                        return Err(HttpError::new(
732                            400,
733                            format!("Invalid WindowUpdate frame length: {}", payload.len())
734                                .as_str(),
735                        ));
736                    }
737                }
738                FrameType::Continuation => {}
739                FrameType::None => {}
740            }
741        }
742    }
743    /// 发送HTTP2认证参数
744    pub fn http2_send_server_settings(&mut self) -> Result<(), HttpError> {
745        let payload = {
746            let mut p = Vec::new();
747            // SETTINGS_ENABLE_PUSH = 0  (对浏览器禁用推送)
748            p.extend_from_slice(&2u16.to_be_bytes());
749            p.extend_from_slice(&0u32.to_be_bytes());
750            // SETTINGS_INITIAL_WINDOW_SIZE = 65535
751            p.extend_from_slice(&4u16.to_be_bytes());
752            p.extend_from_slice(&65_535u32.to_be_bytes());
753            // SETTINGS_MAX_FRAME_SIZE = 16384
754            p.extend_from_slice(&5u16.to_be_bytes());
755            p.extend_from_slice(&16_384u32.to_be_bytes());
756            // 可按需再加 MAX_CONCURRENT_STREAMS 等
757            p
758        };
759        let len = payload.len();
760        let mut f = Vec::with_capacity(9 + len);
761        f.extend_from_slice(&[(len >> 16) as u8, (len >> 8) as u8, len as u8]); // ✅ 正确长度
762        f.push(0x04); // type = SETTINGS
763        f.push(0x00); // flags = none
764        f.extend_from_slice(&0u32.to_be_bytes()); // sid=0
765        f.extend_from_slice(&payload);
766        self.write_all(&f)?;
767        Ok(())
768    }
769    /// 发送对“对端 SETTINGS”的 ACK(len=0, flags=ACK)
770    pub fn http2_settings_ack(&mut self) -> Result<(), HttpError> {
771        let f = [0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00];
772        self.write_all(&f)?;
773        Ok(())
774    }
775    pub fn http2_goaway(&mut self, last_stream_id: u32, error_code: u32) -> Result<(), HttpError> {
776        // 构造帧头
777        let mut frame = Vec::new();
778        frame.extend_from_slice(&[0x00, 0x00, 0x08]); // length
779        frame.push(0x07); // type = GOAWAY
780        frame.push(0x00); // flags = none
781        frame.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); // stream id = 0
782        frame.extend_from_slice(&last_stream_id.to_be_bytes());
783        frame.extend_from_slice(&error_code.to_be_bytes());
784        self.write_all(frame.as_slice())?;
785        Ok(())
786    }
787}
788#[derive(Debug)]
789pub enum FrameType {
790    Data,
791    Headers,
792    RstStream,
793    Settings,
794    Ping,
795    Goaway,
796    WindowUpdate,
797    Continuation,
798    None,
799}
800impl FrameType {
801    pub fn from(code: u8) -> Self {
802        match code {
803            0x00 => Self::Data,
804            0x01 => Self::Headers,
805            0x03 => Self::RstStream,
806            0x04 => Self::Settings,
807            0x06 => Self::Ping,
808            0x07 => Self::Goaway,
809            0x08 => Self::WindowUpdate,
810            0x09 => Self::Continuation,
811            _ => Self::None,
812        }
813    }
814}
815
816pub enum ClientStream {
817    Http(TcpStream),
818    Https(Box<StreamOwned<ClientConnection, TcpStream>>),
819}
820impl ClientStream {
821    pub fn write_all(&mut self, data: &[u8]) -> std::io::Result<()> {
822        match self {
823            ClientStream::Http(e) => e.write_all(data),
824            ClientStream::Https(e) => e.write_all(data),
825        }
826    }
827    pub fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
828        match self {
829            ClientStream::Http(e) => e.read(buf),
830            ClientStream::Https(e) => e.read(buf),
831        }
832    }
833    pub fn read_data(&mut self, buffer: &mut Vec<u8>) -> Result<(), String> {
834        let mut tmp = [0u8; 1024];
835        let n = self.read(&mut tmp).map_err(|e| e.to_string())?;
836        if n == 0 {
837            return Err("unexpected EOF while reading chunk data".to_string());
838        }
839        buffer.extend_from_slice(&tmp[..n]);
840        Ok(())
841    }
842    /// 强制输出
843    pub fn flush(&mut self) -> std::io::Result<()> {
844        match self {
845            ClientStream::Http(e) => e.flush(),
846            ClientStream::Https(e) => e.flush(),
847        }
848    }
849}