@@ -11,167 +11,32 @@ use actix_web::http::header::{ContentType, Header, HttpDate, IfModifiedSince, La
1111use actix_web:: http:: { header, StatusCode , Uri } ;
1212use actix_web:: web:: PayloadConfig ;
1313use actix_web:: {
14- dev:: ServiceResponse , middleware, middleware:: Logger , web, web:: Bytes , App , HttpResponse ,
15- HttpServer ,
14+ dev:: ServiceResponse , middleware, middleware:: Logger , web, App , HttpResponse , HttpServer ,
1615} ;
1716use actix_web:: { HttpResponseBuilder , ResponseError } ;
1817
1918use super :: https:: make_auto_rustls_config;
19+ use super :: response_writer:: ResponseWriter ;
2020use super :: static_content;
2121use actix_web:: body:: MessageBody ;
2222use anyhow:: { bail, Context } ;
2323use chrono:: { DateTime , Utc } ;
2424use futures_util:: stream:: Stream ;
2525use futures_util:: StreamExt ;
2626use std:: borrow:: Cow ;
27- use std:: io:: Write ;
2827use std:: mem;
2928use std:: path:: PathBuf ;
3029use std:: pin:: Pin ;
3130use std:: sync:: Arc ;
32- use std:: task:: Poll ;
3331use std:: time:: SystemTime ;
3432use tokio:: sync:: mpsc;
3533
36- /// If the sending queue exceeds this number of outgoing messages, an error will be thrown
37- /// This prevents a single request from using up all available memory
38-
39- #[ derive( Clone ) ]
40- pub struct ResponseWriter {
41- buffer : Vec < u8 > ,
42- response_bytes : mpsc:: Sender < Bytes > ,
43- }
44-
4534#[ derive( Clone ) ]
4635pub struct RequestContext {
4736 pub is_embedded : bool ,
4837 pub content_security_policy : ContentSecurityPolicy ,
4938}
5039
51- impl ResponseWriter {
52- fn new ( response_bytes : mpsc:: Sender < Bytes > ) -> Self {
53- Self {
54- response_bytes,
55- buffer : Vec :: new ( ) ,
56- }
57- }
58- async fn close_with_error ( & mut self , mut msg : String ) {
59- if !self . response_bytes . is_closed ( ) {
60- if let Err ( e) = self . async_flush ( ) . await {
61- use std:: fmt:: Write ;
62- write ! ( & mut msg, "Unable to flush data: {e}" ) . unwrap ( ) ;
63- }
64- if let Err ( e) = self . response_bytes . send ( msg. into ( ) ) . await {
65- log:: error!( "Unable to send error back to client: {e}" ) ;
66- }
67- }
68- }
69-
70- pub async fn async_flush ( & mut self ) -> std:: io:: Result < ( ) > {
71- if self . buffer . is_empty ( ) {
72- return Ok ( ( ) ) ;
73- }
74- log:: trace!(
75- "Flushing data to client: {}" ,
76- String :: from_utf8_lossy( & self . buffer)
77- ) ;
78- let sender = self
79- . response_bytes
80- . reserve ( )
81- . await
82- . map_err ( |_| std:: io:: ErrorKind :: WouldBlock ) ?;
83- sender. send ( std:: mem:: take ( & mut self . buffer ) . into ( ) ) ;
84- Ok ( ( ) )
85- }
86- }
87-
88- impl Write for ResponseWriter {
89- #[ inline]
90- fn write ( & mut self , buf : & [ u8 ] ) -> std:: io:: Result < usize > {
91- self . buffer . extend_from_slice ( buf) ;
92- Ok ( buf. len ( ) )
93- }
94- fn flush ( & mut self ) -> std:: io:: Result < ( ) > {
95- if self . buffer . is_empty ( ) {
96- return Ok ( ( ) ) ;
97- }
98- log:: trace!(
99- "Flushing data to client: {}" ,
100- String :: from_utf8_lossy( & self . buffer)
101- ) ;
102- self . response_bytes
103- . try_send ( mem:: take ( & mut self . buffer ) . into ( ) )
104- . map_err ( |e|
105- std:: io:: Error :: new (
106- std:: io:: ErrorKind :: WouldBlock ,
107- format ! ( "{e}: Row limit exceeded. The server cannot store more than {} pending messages in memory. Try again later or increase max_pending_rows in the configuration." , self . response_bytes. max_capacity( ) )
108- )
109- )
110- }
111- }
112-
113- pub struct AsyncResponseWriter {
114- poll_sender : tokio_util:: sync:: PollSender < Bytes > ,
115- writer : ResponseWriter ,
116- }
117-
118- impl AsyncResponseWriter {
119- #[ must_use]
120- pub fn new ( writer : ResponseWriter ) -> Self {
121- let sender = writer. response_bytes . clone ( ) ;
122- Self {
123- poll_sender : tokio_util:: sync:: PollSender :: new ( sender) ,
124- writer,
125- }
126- }
127- #[ must_use]
128- pub fn into_inner ( self ) -> ResponseWriter {
129- self . writer
130- }
131- }
132- impl tokio:: io:: AsyncWrite for AsyncResponseWriter {
133- fn poll_write (
134- mut self : Pin < & mut Self > ,
135- _cx : & mut std:: task:: Context < ' _ > ,
136- buf : & [ u8 ] ,
137- ) -> std:: task:: Poll < std:: io:: Result < usize > > {
138- Poll :: Ready ( self . as_mut ( ) . writer . write ( buf) )
139- }
140-
141- fn poll_flush (
142- self : Pin < & mut Self > ,
143- cx : & mut std:: task:: Context < ' _ > ,
144- ) -> std:: task:: Poll < std:: io:: Result < ( ) > > {
145- let Self {
146- poll_sender,
147- writer,
148- } = self . get_mut ( ) ;
149- match poll_sender. poll_reserve ( cx) {
150- Poll :: Ready ( Ok ( ( ) ) ) => {
151- let res = poll_sender. send_item ( std:: mem:: take ( & mut writer. buffer ) . into ( ) ) ;
152- Poll :: Ready ( res. map_err ( |_| std:: io:: ErrorKind :: BrokenPipe . into ( ) ) )
153- }
154- Poll :: Pending => Poll :: Pending ,
155- Poll :: Ready ( Err ( _e) ) => Poll :: Ready ( Err ( std:: io:: ErrorKind :: BrokenPipe . into ( ) ) ) ,
156- }
157- }
158-
159- fn poll_shutdown (
160- self : Pin < & mut Self > ,
161- cx : & mut std:: task:: Context < ' _ > ,
162- ) -> std:: task:: Poll < Result < ( ) , std:: io:: Error > > {
163- self . poll_flush ( cx)
164- }
165- }
166-
167- impl Drop for ResponseWriter {
168- fn drop ( & mut self ) {
169- if let Err ( e) = std:: io:: Write :: flush ( self ) {
170- log:: error!( "Could not flush data to client: {e}" ) ;
171- }
172- }
173- }
174-
17540async fn stream_response ( stream : impl Stream < Item = DbItem > , mut renderer : AnyRenderBodyContext ) {
17641 let mut stream = Box :: pin ( stream) ;
17742
0 commit comments