1use super::custom::server::Session as SessionCustom;
18use super::error_resp;
19use super::subrequest::server::HttpSession as SessionSubrequest;
20use super::v1::server::HttpSession as SessionV1;
21use super::v2::server::{HttpSession as SessionV2, Idle};
22use super::HttpTask;
23use crate::custom_session;
24use crate::protocols::{Digest, SocketAddr, Stream};
25use bytes::{Bytes, BytesMut};
26use http::HeaderValue;
27use http::{header::AsHeaderName, HeaderMap};
28use pingora_error::{Error, Result};
29use pingora_http::{RequestHeader, ResponseHeader};
30use std::any::Any;
31use std::time::Duration;
32
33#[derive(Debug)]
35pub struct ReusableHttpStream {
36 stream: Stream,
37 pipelined_prefix: Option<BytesMut>,
38}
39
40impl ReusableHttpStream {
41 pub(crate) fn new(stream: Stream, pipelined_prefix: Option<BytesMut>) -> Self {
42 Self {
43 stream,
44 pipelined_prefix,
45 }
46 }
47
48 pub fn into_parts(self) -> (Stream, Option<BytesMut>) {
51 (self.stream, self.pipelined_prefix)
52 }
53}
54
55pub enum Session {
57 H1(SessionV1),
58 H2(SessionV2),
59 Subrequest(SessionSubrequest),
60 Custom(Box<dyn SessionCustom>),
61}
62
63impl Session {
64 pub fn new_http1(stream: Stream) -> Self {
66 Self::H1(SessionV1::new(stream))
67 }
68
69 pub fn new_http2(session: SessionV2) -> Self {
71 Self::H2(session)
72 }
73
74 pub fn new_subrequest(session: SessionSubrequest) -> Self {
76 Self::Subrequest(session)
77 }
78
79 pub fn new_custom(session: Box<dyn SessionCustom>) -> Self {
81 Self::Custom(session)
82 }
83
84 pub fn is_http2(&self) -> bool {
86 matches!(self, Self::H2(_))
87 }
88
89 pub fn is_subrequest(&self) -> bool {
91 matches!(self, Self::Subrequest(_))
92 }
93
94 pub fn is_custom(&self) -> bool {
96 matches!(self, Self::Custom(_))
97 }
98
99 pub fn session_type(&self) -> &'static str {
101 match self {
102 Self::H1(_) => "h1",
103 Self::H2(_) => "h2",
104 Self::Subrequest(_) => "subrequest",
105 Self::Custom(_) => "custom",
106 }
107 }
108
109 pub async fn read_request(&mut self) -> Result<bool> {
115 match self {
116 Self::H1(s) => {
117 let read = s.read_request().await?;
118 Ok(read.is_some())
119 }
120 Self::H2(_) => Ok(true),
122 Self::Subrequest(s) => {
123 let read = s.read_request().await?;
124 Ok(read.is_some())
125 }
126 Self::Custom(_) => Ok(true),
127 }
128 }
129
130 pub fn req_header(&self) -> &RequestHeader {
134 match self {
135 Self::H1(s) => s.req_header(),
136 Self::H2(s) => s.req_header(),
137 Self::Subrequest(s) => s.req_header(),
138 Self::Custom(s) => s.req_header(),
139 }
140 }
141
142 pub fn req_header_mut(&mut self) -> &mut RequestHeader {
146 match self {
147 Self::H1(s) => s.req_header_mut(),
148 Self::H2(s) => s.req_header_mut(),
149 Self::Subrequest(s) => s.req_header_mut(),
150 Self::Custom(s) => s.req_header_mut(),
151 }
152 }
153
154 pub fn get_header<K: AsHeaderName>(&self, key: K) -> Option<&HeaderValue> {
159 self.req_header().headers.get(key)
160 }
161
162 pub fn get_header_bytes<K: AsHeaderName>(&self, key: K) -> &[u8] {
165 self.get_header(key).map_or(b"", |v| v.as_bytes())
166 }
167
168 pub async fn read_request_body(&mut self) -> Result<Option<Bytes>> {
170 match self {
171 Self::H1(s) => s.read_body_bytes().await,
172 Self::H2(s) => s.read_body_bytes().await,
173 Self::Subrequest(s) => s.read_body_bytes().await,
174 Self::Custom(s) => s.read_body_bytes().await,
175 }
176 }
177
178 pub async fn drain_request_body(&mut self) -> Result<()> {
183 match self {
184 Self::H1(s) => s.drain_request_body().await,
185 Self::H2(s) => s.drain_request_body().await,
186 Self::Subrequest(s) => s.drain_request_body().await,
187 Self::Custom(s) => s.drain_request_body().await,
188 }
189 }
190
191 pub async fn write_response_header(&mut self, resp: Box<ResponseHeader>) -> Result<()> {
195 match self {
196 Self::H1(s) => {
197 s.write_response_header(resp).await?;
198 Ok(())
199 }
200 Self::H2(s) => s.write_response_header(resp, false),
201 Self::Subrequest(s) => {
202 s.write_response_header(resp).await?;
203 Ok(())
204 }
205 Self::Custom(s) => s.write_response_header(resp, false).await,
206 }
207 }
208
209 pub async fn write_response_header_ref(&mut self, resp: &ResponseHeader) -> Result<()> {
211 match self {
212 Self::H1(s) => {
213 s.write_response_header_ref(resp).await?;
214 Ok(())
215 }
216 Self::H2(s) => s.write_response_header_ref(resp, false),
217 Self::Subrequest(s) => {
218 s.write_response_header_ref(resp).await?;
219 Ok(())
220 }
221 Self::Custom(s) => s.write_response_header_ref(resp, false).await,
222 }
223 }
224
225 pub async fn write_response_body(&mut self, data: Bytes, end: bool) -> Result<()> {
227 if data.is_empty() && !end {
228 return Ok(());
232 }
233 match self {
234 Self::H1(s) => {
235 if !data.is_empty() {
236 s.write_body(&data).await?;
237 }
238 if end {
239 s.finish_body().await?;
240 }
241 Ok(())
242 }
243 Self::H2(s) => s.write_body(data, end).await,
244 Self::Subrequest(s) => {
245 s.write_body(data).await?;
246 Ok(())
247 }
248 Self::Custom(s) => s.write_body(data, end).await,
249 }
250 }
251
252 pub async fn write_response_trailers(&mut self, trailers: HeaderMap) -> Result<()> {
254 match self {
255 Self::H1(_) => Ok(()), Self::H2(s) => s.write_trailers(trailers),
257 Self::Subrequest(s) => s.write_trailers(Some(Box::new(trailers))).await,
258 Self::Custom(s) => s.write_trailers(trailers).await,
259 }
260 }
261
262 pub async fn finish(self) -> Result<Option<ReusableHttpStream>> {
269 match self {
270 Self::H1(mut s) => {
271 s.finish_body().await?;
273 s.reuse().await
274 }
275 Self::H2(mut s) => {
276 s.finish()?;
277 Ok(None)
278 }
279 Self::Subrequest(mut s) => {
280 s.finish().await?;
281 Ok(None)
282 }
283 Self::Custom(mut s) => {
284 s.finish().await?;
285 Ok(None)
286 }
287 }
288 }
289
290 pub fn on_proxy_failure(&mut self, e: Box<Error>) {
296 match self {
297 Self::H1(_) | Self::H2(_) | Self::Custom(_) => {
298 }
301 Self::Subrequest(ref mut s) => s.on_proxy_failure(e),
302 }
303 }
304
305 pub async fn response_duplex_vec(&mut self, tasks: Vec<HttpTask>) -> Result<bool> {
306 match self {
307 Self::H1(s) => s.response_duplex_vec(tasks).await,
308 Self::H2(s) => s.response_duplex_vec(tasks).await,
309 Self::Subrequest(s) => s.response_duplex_vec(tasks).await,
310 Self::Custom(s) => s.response_duplex_vec(tasks).await,
311 }
312 }
313
314 pub fn set_keepalive(&mut self, duration: Option<u64>) {
317 match self {
318 Self::H1(s) => s.set_server_keepalive(duration),
319 Self::H2(_) => {}
320 Self::Subrequest(_) => {}
321 Self::Custom(_) => {}
322 }
323 }
324
325 pub fn get_keepalive(&self) -> Option<u64> {
328 match self {
329 Self::H1(s) => s.get_keepalive_timeout(),
330 Self::H2(_) => None,
331 Self::Subrequest(_) => None,
332 Self::Custom(_) => None,
333 }
334 }
335
336 pub fn set_keepalive_reuses_remaining(&mut self, reuses: Option<u32>) {
339 if let Self::H1(s) = self {
340 s.set_keepalive_reuses_remaining(reuses);
341 }
342 }
343
344 pub fn get_keepalive_reuses_remaining(&self) -> Option<u32> {
348 if let Self::H1(s) = self {
349 s.get_keepalive_reuses_remaining()
350 } else {
351 None
352 }
353 }
354
355 pub fn set_connection_user_context(&mut self, ctx: Option<Box<dyn Any + Send + Sync>>) {
359 if let Self::H1(s) = self {
360 s.set_connection_user_context(ctx);
361 }
362 }
363
364 pub fn take_connection_user_context(&mut self) -> Option<Box<dyn Any + Send + Sync>> {
368 if let Self::H1(s) = self {
369 s.take_connection_user_context()
370 } else {
371 None
372 }
373 }
374
375 pub fn set_read_timeout(&mut self, timeout: Option<Duration>) {
380 match self {
381 Self::H1(s) => s.set_read_timeout(timeout),
382 Self::H2(_) => {}
383 Self::Subrequest(s) => s.set_read_timeout(timeout),
384 Self::Custom(c) => c.set_read_timeout(timeout),
385 }
386 }
387
388 pub fn get_read_timeout(&self) -> Option<Duration> {
390 match self {
391 Self::H1(s) => s.get_read_timeout(),
392 Self::H2(_) => None,
393 Self::Subrequest(s) => s.get_read_timeout(),
394 Self::Custom(s) => s.get_read_timeout(),
395 }
396 }
397
398 pub fn set_write_timeout(&mut self, timeout: Option<Duration>) {
402 match self {
403 Self::H1(s) => s.set_write_timeout(timeout),
404 Self::H2(s) => s.set_write_timeout(timeout),
405 Self::Subrequest(s) => s.set_write_timeout(timeout),
406 Self::Custom(c) => c.set_write_timeout(timeout),
407 }
408 }
409
410 pub fn get_write_timeout(&self) -> Option<Duration> {
412 match self {
413 Self::H1(s) => s.get_write_timeout(),
414 Self::H2(s) => s.get_write_timeout(),
415 Self::Subrequest(s) => s.get_write_timeout(),
416 Self::Custom(s) => s.get_write_timeout(),
417 }
418 }
419
420 pub fn set_total_drain_timeout(&mut self, timeout: Option<Duration>) {
427 match self {
428 Self::H1(s) => s.set_total_drain_timeout(timeout),
429 Self::H2(s) => s.set_total_drain_timeout(timeout),
430 Self::Subrequest(s) => s.set_total_drain_timeout(timeout),
431 Self::Custom(c) => c.set_total_drain_timeout(timeout),
432 }
433 }
434
435 pub fn get_total_drain_timeout(&self) -> Option<Duration> {
437 match self {
438 Self::H1(s) => s.get_total_drain_timeout(),
439 Self::H2(s) => s.get_total_drain_timeout(),
440 Self::Subrequest(s) => s.get_total_drain_timeout(),
441 Self::Custom(s) => s.get_total_drain_timeout(),
442 }
443 }
444
445 pub fn set_min_send_rate(&mut self, rate: Option<usize>) {
456 match self {
457 Self::H1(s) => s.set_min_send_rate(rate),
458 Self::H2(_) => {}
459 Self::Subrequest(_) => {}
460 Self::Custom(_) => {}
461 }
462 }
463
464 pub fn set_ignore_info_resp(&mut self, ignore: bool) {
473 match self {
474 Self::H1(s) => s.set_ignore_info_resp(ignore),
475 Self::H2(_) => {} Self::Subrequest(_) => {}
477 Self::Custom(_) => {} }
479 }
480
481 pub fn set_close_on_response_before_downstream_finish(&mut self, close: bool) {
486 match self {
487 Self::H1(s) => s.set_close_on_response_before_downstream_finish(close),
488 Self::H2(_) => {} Self::Subrequest(_) => {} Self::Custom(_) => {} }
492 }
493
494 pub fn set_abort_on_close(&mut self, abort: bool) {
502 match self {
503 Self::H1(s) => s.set_abort_on_close(abort),
504 Self::H2(_) => {}
505 Self::Subrequest(_) => {}
506 Self::Custom(_) => {}
507 }
508 }
509
510 pub fn request_summary(&self) -> String {
513 match self {
514 Self::H1(s) => s.request_summary(),
515 Self::H2(s) => s.request_summary(),
516 Self::Subrequest(s) => s.request_summary(),
517 Self::Custom(s) => s.request_summary(),
518 }
519 }
520
521 pub fn response_written(&self) -> Option<&ResponseHeader> {
524 match self {
525 Self::H1(s) => s.response_written(),
526 Self::H2(s) => s.response_written(),
527 Self::Subrequest(s) => s.response_written(),
528 Self::Custom(s) => s.response_written(),
529 }
530 }
531
532 pub async fn shutdown(&mut self) {
541 match self {
542 Self::H1(s) => s.shutdown().await,
543 Self::H2(s) => s.shutdown(),
544 Self::Subrequest(s) => s.shutdown(),
545 Self::Custom(s) => s.abandon("shutdown").await,
546 }
547 }
548
549 pub fn shutdown_with_reason(&mut self, reason: h2::Reason) {
557 if let Self::H2(s) = self {
558 s.shutdown_with_reason(reason);
559 }
560 }
561
562 pub fn to_h1_raw(&self) -> Bytes {
563 match self {
564 Self::H1(s) => s.get_headers_raw_bytes(),
565 Self::H2(s) => s.pseudo_raw_h1_request_header(),
566 Self::Subrequest(s) => s.get_headers_raw_bytes(),
567 Self::Custom(c) => c.pseudo_raw_h1_request_header(),
568 }
569 }
570
571 pub fn is_body_done(&mut self) -> bool {
573 match self {
574 Self::H1(s) => s.is_body_done(),
575 Self::H2(s) => s.is_body_done(),
576 Self::Subrequest(s) => s.is_body_done(),
577 Self::Custom(s) => s.is_body_done(),
578 }
579 }
580
581 pub async fn finish_body(&mut self) -> Result<()> {
587 match self {
588 Self::H1(s) => s.finish_body().await.map(|_| ()),
589 Self::H2(s) => s.finish(),
590 Self::Subrequest(s) => s.finish().await.map(|_| ()),
591 Self::Custom(s) => s.finish().await,
592 }
593 }
594
595 pub fn generate_error(error: u16) -> ResponseHeader {
596 match error {
597 502 => error_resp::HTTP_502_RESPONSE.clone(),
599 400 => error_resp::HTTP_400_RESPONSE.clone(),
600 _ => error_resp::gen_error_response(error),
601 }
602 }
603
604 pub async fn respond_error(&mut self, error: u16) -> Result<()> {
606 self.respond_error_with_body(error, Bytes::default()).await
607 }
608
609 pub async fn respond_error_with_body(&mut self, error: u16, body: Bytes) -> Result<()> {
611 let mut resp = Self::generate_error(error);
612 if !body.is_empty() {
613 resp.set_content_length(body.len())?
615 }
616 self.write_error_response(resp, body).await
617 }
618
619 pub async fn write_error_response(&mut self, resp: ResponseHeader, body: Bytes) -> Result<()> {
621 self.set_keepalive(None);
628
629 if let Some(resp_written) = self.response_written().as_ref() {
633 if !resp_written.status.is_informational() || resp_written.status == 101 {
634 return Ok(());
635 }
636 }
637
638 self.write_response_header(Box::new(resp)).await?;
639
640 if !body.is_empty() {
641 self.write_response_body(body, true).await?;
642 } else {
643 self.finish_body().await?;
644 }
645
646 custom_session!(self.finish_custom().await?);
647
648 Ok(())
649 }
650
651 pub fn is_body_empty(&mut self) -> bool {
653 match self {
654 Self::H1(s) => s.is_body_empty(),
655 Self::H2(s) => s.is_body_empty(),
656 Self::Subrequest(s) => s.is_body_empty(),
657 Self::Custom(s) => s.is_body_empty(),
658 }
659 }
660
661 pub fn retry_buffer_truncated(&self) -> bool {
662 match self {
663 Self::H1(s) => s.retry_buffer_truncated(),
664 Self::H2(s) => s.retry_buffer_truncated(),
665 Self::Subrequest(s) => s.retry_buffer_truncated(),
666 Self::Custom(s) => s.retry_buffer_truncated(),
667 }
668 }
669
670 pub fn enable_retry_buffering(&mut self) {
671 match self {
672 Self::H1(s) => s.enable_retry_buffering(),
673 Self::H2(s) => s.enable_retry_buffering(),
674 Self::Subrequest(s) => s.enable_retry_buffering(),
675 Self::Custom(s) => s.enable_retry_buffering(),
676 }
677 }
678
679 pub fn get_retry_buffer(&self) -> Option<Bytes> {
680 match self {
681 Self::H1(s) => s.get_retry_buffer(),
682 Self::H2(s) => s.get_retry_buffer(),
683 Self::Subrequest(s) => s.get_retry_buffer(),
684 Self::Custom(s) => s.get_retry_buffer(),
685 }
686 }
687
688 pub async fn read_body_or_idle(&mut self, no_body_expected: bool) -> Result<Option<Bytes>> {
691 match self {
692 Self::H1(s) => s.read_body_or_idle(no_body_expected).await,
693 Self::H2(s) => s.read_body_or_idle(no_body_expected).await,
694 Self::Subrequest(s) => s.read_body_or_idle(no_body_expected).await,
695 Self::Custom(s) => s.read_body_or_idle(no_body_expected).await,
696 }
697 }
698
699 pub fn watch_h2_stream_close(&mut self) -> Option<Idle<'_>> {
706 match self {
707 Self::H2(s) => Some(s.idle()),
708 _ => None,
709 }
710 }
711
712 pub fn as_http1(&self) -> Option<&SessionV1> {
713 match self {
714 Self::H1(s) => Some(s),
715 Self::H2(_) => None,
716 Self::Subrequest(_) => None,
717 Self::Custom(_) => None,
718 }
719 }
720
721 pub fn as_http2(&self) -> Option<&SessionV2> {
722 match self {
723 Self::H1(_) => None,
724 Self::H2(s) => Some(s),
725 Self::Subrequest(_) => None,
726 Self::Custom(_) => None,
727 }
728 }
729
730 pub fn as_subrequest(&self) -> Option<&SessionSubrequest> {
731 match self {
732 Self::H1(_) => None,
733 Self::H2(_) => None,
734 Self::Subrequest(s) => Some(s),
735 Self::Custom(_) => None,
736 }
737 }
738
739 pub fn as_subrequest_mut(&mut self) -> Option<&mut SessionSubrequest> {
740 match self {
741 Self::H1(_) => None,
742 Self::H2(_) => None,
743 Self::Subrequest(s) => Some(s),
744 Self::Custom(_) => None,
745 }
746 }
747
748 pub fn as_custom(&self) -> Option<&dyn SessionCustom> {
749 match self {
750 Self::H1(_) => None,
751 Self::H2(_) => None,
752 Self::Subrequest(_) => None,
753 Self::Custom(c) => Some(c.as_ref()),
754 }
755 }
756
757 pub fn as_custom_mut(&mut self) -> Option<&mut Box<dyn SessionCustom>> {
758 match self {
759 Self::H1(_) => None,
760 Self::H2(_) => None,
761 Self::Subrequest(_) => None,
762 Self::Custom(c) => Some(c),
763 }
764 }
765
766 pub async fn write_continue_response(&mut self) -> Result<()> {
768 match self {
769 Self::H1(s) => s.write_continue_response().await,
770 Self::H2(s) => s.write_response_header(
771 Box::new(ResponseHeader::build(100, Some(0)).unwrap()),
772 false,
773 ),
774 Self::Subrequest(s) => s.write_continue_response().await,
775 Self::Custom(s) => {
777 s.write_response_header(
778 Box::new(ResponseHeader::build(100, Some(0)).unwrap()),
779 false,
780 )
781 .await
782 }
783 }
784 }
785
786 pub fn is_upgrade_req(&self) -> bool {
788 match self {
789 Self::H1(s) => s.is_upgrade_req(),
790 Self::H2(_) => false,
791 Self::Subrequest(s) => s.is_upgrade_req(),
792 Self::Custom(s) => s.is_upgrade_req(),
793 }
794 }
795
796 pub fn is_upgrade(&self, header: &ResponseHeader) -> Option<bool> {
802 match self {
803 Self::H1(s) => s.is_upgrade(header),
804 Self::H2(_) => None,
805 Self::Subrequest(s) => s.is_upgrade(header),
806 Self::Custom(s) => {
807 if s.is_upgrade_req() {
808 Some(super::v1::common::is_upgrade_resp(header))
809 } else {
810 None
811 }
812 }
813 }
814 }
815
816 pub fn was_upgraded(&self) -> bool {
818 match self {
819 Self::H1(s) => s.was_upgraded(),
820 Self::H2(_) => false,
821 Self::Subrequest(s) => s.was_upgraded(),
822 Self::Custom(s) => s.was_upgraded(),
823 }
824 }
825
826 pub fn body_bytes_sent(&self) -> usize {
828 match self {
829 Self::H1(s) => s.body_bytes_sent(),
830 Self::H2(s) => s.body_bytes_sent(),
831 Self::Subrequest(s) => s.body_bytes_sent(),
832 Self::Custom(s) => s.body_bytes_sent(),
833 }
834 }
835
836 pub fn body_bytes_read(&self) -> usize {
838 match self {
839 Self::H1(s) => s.body_bytes_read(),
840 Self::H2(s) => s.body_bytes_read(),
841 Self::Subrequest(s) => s.body_bytes_read(),
842 Self::Custom(s) => s.body_bytes_read(),
843 }
844 }
845
846 pub fn digest(&self) -> Option<&Digest> {
848 match self {
849 Self::H1(s) => Some(s.digest()),
850 Self::H2(s) => s.digest(),
851 Self::Subrequest(s) => s.digest(),
852 Self::Custom(s) => s.digest(),
853 }
854 }
855
856 pub fn digest_mut(&mut self) -> Option<&mut Digest> {
860 match self {
861 Self::H1(s) => Some(s.digest_mut()),
862 Self::H2(s) => s.digest_mut(),
863 Self::Subrequest(s) => s.digest_mut(),
864 Self::Custom(s) => s.digest_mut(),
865 }
866 }
867
868 pub fn client_addr(&self) -> Option<&SocketAddr> {
870 match self {
871 Self::H1(s) => s.client_addr(),
872 Self::H2(s) => s.client_addr(),
873 Self::Subrequest(s) => s.client_addr(),
874 Self::Custom(s) => s.client_addr(),
875 }
876 }
877
878 pub fn server_addr(&self) -> Option<&SocketAddr> {
880 match self {
881 Self::H1(s) => s.server_addr(),
882 Self::H2(s) => s.server_addr(),
883 Self::Subrequest(s) => s.server_addr(),
884 Self::Custom(s) => s.server_addr(),
885 }
886 }
887
888 pub fn stream(&self) -> Option<&Stream> {
891 match self {
892 Self::H1(s) => Some(s.stream()),
893 Self::H2(_) => None,
894 Self::Subrequest(_) => None,
895 Self::Custom(_) => None,
896 }
897 }
898
899 pub fn supports_proxy_task_api(&self) -> bool {
905 match self {
906 Self::H1(s) => s.proxy_tasks_enabled(),
907 Self::Subrequest(s) => s.proxy_tasks_enabled(),
908 Self::Custom(s) => s.proxy_tasks_enabled(),
909 Self::H2(_) => false,
910 }
911 }
912
913 pub fn set_proxy_tasks_enabled(&mut self, enabled: bool) {
915 match self {
916 Self::H1(s) => s.set_proxy_tasks_enabled(enabled),
917 Self::Subrequest(s) => s.set_proxy_tasks_enabled(enabled),
918 Self::Custom(s) => s.set_proxy_tasks_enabled(enabled),
919 Self::H2(_) => {}
920 }
921 }
922
923 pub fn pipelining_enabled(&self) -> bool {
929 match self {
930 Self::H1(s) => s.pipelining_enabled(),
931 _ => false,
932 }
933 }
934
935 pub fn set_pipelining_enabled(&mut self, enabled: bool) {
941 if let Self::H1(s) = self {
942 s.set_pipelining_enabled(enabled);
943 }
944 }
945
946 pub fn set_pipelined_prefix(&mut self, prefix: BytesMut) {
952 if let Self::H1(s) = self {
953 s.set_pipelined_prefix(prefix);
954 }
955 }
956
957 #[track_caller]
965 pub fn send_downstream_proxy_task(&mut self, task: HttpTask) {
966 match self {
967 Self::H1(s) => s.send_proxy_task(task),
968 Self::H2(_) => panic!("H2 proxy task API not yet implemented"),
969 Self::Subrequest(s) => s.send_proxy_task(task),
970 Self::Custom(s) => s.send_proxy_task(task),
971 }
972 }
973
974 pub fn has_pending_downstream_proxy_tasks(&self) -> bool {
978 match self {
979 Self::H1(s) => s.has_pending_proxy_tasks(),
980 Self::H2(_) => false, Self::Subrequest(s) => s.has_pending_proxy_tasks(),
982 Self::Custom(s) => s.has_pending_proxy_tasks(),
983 }
984 }
985
986 pub async fn write_downstream_proxy_tasks(&mut self) -> Result<bool> {
995 match self {
996 Self::H1(s) => s.write_proxy_tasks().await,
997 Self::H2(_) => panic!("H2 proxy task API not yet implemented"),
998 Self::Subrequest(s) => s.write_proxy_tasks().await,
999 Self::Custom(s) => s.write_proxy_tasks().await,
1000 }
1001 }
1002}
1003
1004#[cfg(test)]
1005mod tests {
1006 use super::*;
1007 use crate::protocols::http::custom::CustomMessageWrite;
1008 use async_trait::async_trait;
1009 use futures::Stream;
1010 use std::panic::{catch_unwind, AssertUnwindSafe};
1011 use std::sync::{Arc, Mutex};
1012
1013 #[tokio::test]
1014 async fn custom_proxy_task_defaults_are_opted_out_and_fail_loudly() {
1015 let mut session = Session::new_custom(Box::new(()));
1016
1017 assert!(!session.supports_proxy_task_api());
1018 session.set_proxy_tasks_enabled(true);
1019 assert!(!session.supports_proxy_task_api());
1020 assert!(!session.has_pending_downstream_proxy_tasks());
1021
1022 assert!(catch_unwind(AssertUnwindSafe(|| {
1023 session.send_downstream_proxy_task(HttpTask::Done);
1024 }))
1025 .is_err());
1026
1027 let join = tokio::spawn(async move { session.write_downstream_proxy_tasks().await });
1028 assert!(join.await.unwrap_err().is_panic());
1029 }
1030
1031 #[tokio::test]
1032 async fn custom_proxy_task_methods_delegate_to_the_custom_session() {
1033 let mut session = Session::new_custom(Box::new(ProxyTaskCustom::new()));
1034
1035 assert!(!session.supports_proxy_task_api());
1036 session.set_proxy_tasks_enabled(true);
1037 assert!(session.supports_proxy_task_api());
1038
1039 session.send_downstream_proxy_task(HttpTask::Done);
1040 assert!(session.has_pending_downstream_proxy_tasks());
1041 assert!(session.write_downstream_proxy_tasks().await.unwrap());
1042 assert!(!session.has_pending_downstream_proxy_tasks());
1043 }
1044
1045 #[tokio::test]
1051 async fn custom_session_shutdown_signals_an_incomplete_message() {
1052 let shutdown_calls = Arc::new(Mutex::new(Vec::new()));
1053 let mut session = Session::new_custom(Box::new(ProxyTaskCustom::with_shutdown_calls(
1054 shutdown_calls.clone(),
1055 )));
1056
1057 session.shutdown().await;
1058
1059 assert_eq!(*shutdown_calls.lock().unwrap(), ["abandon(shutdown)"]);
1060 }
1061
1062 struct ProxyTaskCustom {
1063 header: RequestHeader,
1064 enabled: bool,
1065 tasks: Vec<HttpTask>,
1066 shutdown_calls: Arc<Mutex<Vec<String>>>,
1067 }
1068
1069 impl ProxyTaskCustom {
1070 fn new() -> Self {
1071 Self {
1072 header: RequestHeader::build("GET", b"/", None).unwrap(),
1073 enabled: false,
1074 tasks: Vec::new(),
1075 shutdown_calls: Arc::new(Mutex::new(Vec::new())),
1076 }
1077 }
1078
1079 fn with_shutdown_calls(shutdown_calls: Arc<Mutex<Vec<String>>>) -> Self {
1080 Self {
1081 shutdown_calls,
1082 ..Self::new()
1083 }
1084 }
1085 }
1086
1087 #[async_trait]
1088 impl SessionCustom for ProxyTaskCustom {
1089 fn req_header(&self) -> &RequestHeader {
1090 &self.header
1091 }
1092
1093 fn req_header_mut(&mut self) -> &mut RequestHeader {
1094 &mut self.header
1095 }
1096
1097 async fn read_body_bytes(&mut self) -> Result<Option<Bytes>> {
1098 unreachable!("not used by proxy task dispatch test")
1099 }
1100
1101 async fn drain_request_body(&mut self) -> Result<()> {
1102 unreachable!("not used by proxy task dispatch test")
1103 }
1104
1105 async fn write_response_header(
1106 &mut self,
1107 _resp: Box<ResponseHeader>,
1108 _end: bool,
1109 ) -> Result<()> {
1110 unreachable!("not used by proxy task dispatch test")
1111 }
1112
1113 async fn write_response_header_ref(
1114 &mut self,
1115 _resp: &ResponseHeader,
1116 _end: bool,
1117 ) -> Result<()> {
1118 unreachable!("not used by proxy task dispatch test")
1119 }
1120
1121 async fn write_body(&mut self, _data: Bytes, _end: bool) -> Result<()> {
1122 unreachable!("not used by proxy task dispatch test")
1123 }
1124
1125 async fn write_trailers(&mut self, _trailers: HeaderMap) -> Result<()> {
1126 unreachable!("not used by proxy task dispatch test")
1127 }
1128
1129 async fn response_duplex_vec(&mut self, _tasks: Vec<HttpTask>) -> Result<bool> {
1130 unreachable!("not used by proxy task dispatch test")
1131 }
1132
1133 fn proxy_tasks_enabled(&self) -> bool {
1134 self.enabled
1135 }
1136
1137 fn set_proxy_tasks_enabled(&mut self, enabled: bool) {
1138 self.enabled = enabled;
1139 }
1140
1141 fn send_proxy_task(&mut self, task: HttpTask) {
1142 self.tasks.push(task);
1143 }
1144
1145 fn has_pending_proxy_tasks(&self) -> bool {
1146 !self.tasks.is_empty()
1147 }
1148
1149 async fn write_proxy_tasks(&mut self) -> Result<bool> {
1150 self.tasks.clear();
1151 Ok(true)
1152 }
1153
1154 fn set_read_timeout(&mut self, _timeout: Option<Duration>) {
1155 unreachable!("not used by proxy task dispatch test")
1156 }
1157
1158 fn get_read_timeout(&self) -> Option<Duration> {
1159 unreachable!("not used by proxy task dispatch test")
1160 }
1161
1162 fn set_write_timeout(&mut self, _timeout: Option<Duration>) {
1163 unreachable!("not used by proxy task dispatch test")
1164 }
1165
1166 fn get_write_timeout(&self) -> Option<Duration> {
1167 unreachable!("not used by proxy task dispatch test")
1168 }
1169
1170 fn set_total_drain_timeout(&mut self, _timeout: Option<Duration>) {
1171 unreachable!("not used by proxy task dispatch test")
1172 }
1173
1174 fn get_total_drain_timeout(&self) -> Option<Duration> {
1175 unreachable!("not used by proxy task dispatch test")
1176 }
1177
1178 fn request_summary(&self) -> String {
1179 unreachable!("not used by proxy task dispatch test")
1180 }
1181
1182 fn response_written(&self) -> Option<&ResponseHeader> {
1183 unreachable!("not used by proxy task dispatch test")
1184 }
1185
1186 async fn shutdown(&mut self, code: u32, ctx: &str) {
1187 self.shutdown_calls
1188 .lock()
1189 .unwrap()
1190 .push(format!("shutdown({code}, {ctx})"));
1191 }
1192
1193 async fn abandon(&mut self, ctx: &str) {
1194 self.shutdown_calls
1195 .lock()
1196 .unwrap()
1197 .push(format!("abandon({ctx})"));
1198 }
1199
1200 fn is_body_done(&mut self) -> bool {
1201 unreachable!("not used by proxy task dispatch test")
1202 }
1203
1204 async fn finish(&mut self) -> Result<()> {
1205 unreachable!("not used by proxy task dispatch test")
1206 }
1207
1208 fn is_body_empty(&mut self) -> bool {
1209 unreachable!("not used by proxy task dispatch test")
1210 }
1211
1212 async fn read_body_or_idle(&mut self, _no_body_expected: bool) -> Result<Option<Bytes>> {
1213 unreachable!("not used by proxy task dispatch test")
1214 }
1215
1216 fn body_bytes_sent(&self) -> usize {
1217 unreachable!("not used by proxy task dispatch test")
1218 }
1219
1220 fn body_bytes_read(&self) -> usize {
1221 unreachable!("not used by proxy task dispatch test")
1222 }
1223
1224 fn digest(&self) -> Option<&Digest> {
1225 unreachable!("not used by proxy task dispatch test")
1226 }
1227
1228 fn digest_mut(&mut self) -> Option<&mut Digest> {
1229 unreachable!("not used by proxy task dispatch test")
1230 }
1231
1232 fn client_addr(&self) -> Option<&SocketAddr> {
1233 unreachable!("not used by proxy task dispatch test")
1234 }
1235
1236 fn server_addr(&self) -> Option<&SocketAddr> {
1237 unreachable!("not used by proxy task dispatch test")
1238 }
1239
1240 fn pseudo_raw_h1_request_header(&self) -> Bytes {
1241 unreachable!("not used by proxy task dispatch test")
1242 }
1243
1244 fn enable_retry_buffering(&mut self) {
1245 unreachable!("not used by proxy task dispatch test")
1246 }
1247
1248 fn retry_buffer_truncated(&self) -> bool {
1249 unreachable!("not used by proxy task dispatch test")
1250 }
1251
1252 fn get_retry_buffer(&self) -> Option<Bytes> {
1253 unreachable!("not used by proxy task dispatch test")
1254 }
1255
1256 async fn finish_custom(&mut self) -> Result<()> {
1257 unreachable!("not used by proxy task dispatch test")
1258 }
1259
1260 fn take_custom_message_reader(
1261 &mut self,
1262 ) -> Option<Box<dyn Stream<Item = Result<Bytes>> + Unpin + Send + Sync + 'static>> {
1263 unreachable!("not used by proxy task dispatch test")
1264 }
1265
1266 fn restore_custom_message_reader(
1267 &mut self,
1268 _reader: Box<dyn Stream<Item = Result<Bytes>> + Unpin + Send + Sync + 'static>,
1269 ) -> Result<()> {
1270 unreachable!("not used by proxy task dispatch test")
1271 }
1272
1273 fn take_custom_message_writer(&mut self) -> Option<Box<dyn CustomMessageWrite>> {
1274 unreachable!("not used by proxy task dispatch test")
1275 }
1276
1277 fn restore_custom_message_writer(
1278 &mut self,
1279 _writer: Box<dyn CustomMessageWrite>,
1280 ) -> Result<()> {
1281 unreachable!("not used by proxy task dispatch test")
1282 }
1283 }
1284}