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
23pub 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
35pub 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 if !self.pending.is_empty() {
89 let message = Message::parse_message(&mut self.pending, deflate);
90 match message.message_type {
91 MessageType::TimeOut => {} _ => 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 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 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 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 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 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 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 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 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; 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 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; 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 pub fn http2_send_server_settings(&mut self) -> Result<(), HttpError> {
745 let payload = {
746 let mut p = Vec::new();
747 p.extend_from_slice(&2u16.to_be_bytes());
749 p.extend_from_slice(&0u32.to_be_bytes());
750 p.extend_from_slice(&4u16.to_be_bytes());
752 p.extend_from_slice(&65_535u32.to_be_bytes());
753 p.extend_from_slice(&5u16.to_be_bytes());
755 p.extend_from_slice(&16_384u32.to_be_bytes());
756 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]); f.push(0x04); f.push(0x00); f.extend_from_slice(&0u32.to_be_bytes()); f.extend_from_slice(&payload);
766 self.write_all(&f)?;
767 Ok(())
768 }
769 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 let mut frame = Vec::new();
778 frame.extend_from_slice(&[0x00, 0x00, 0x08]); frame.push(0x07); frame.push(0x00); frame.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); 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 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}