1- use crate :: errors:: PrerenderError ;
2- use crate :: { IGNORED_EXTENSIONS , USER_AGENTS } ;
31use actix_service:: { Service , Transform } ;
42use actix_utils:: future;
53use actix_utils:: future:: Ready ;
64use actix_web:: body:: BoxBody ;
7-
85use actix_web:: dev:: { ServiceRequest , ServiceResponse } ;
96use actix_web:: http:: header:: HeaderMap ;
107use actix_web:: http:: uri:: PathAndQuery ;
@@ -13,48 +10,59 @@ use actix_web::{Error, HttpResponse};
1310use futures_util:: future:: LocalBoxFuture ;
1411use futures_util:: TryFutureExt ;
1512use reqwest:: Client ;
13+ use std:: rc:: Rc ;
1614use url:: Url ;
1715
16+ use crate :: errors:: PrerenderError ;
17+ use crate :: { IGNORED_EXTENSIONS , USER_AGENTS } ;
18+
1819#[ derive( Debug , Clone ) ]
1920pub struct Prerender {
20- prerender_service_url : Url ,
21- inner_client : Client ,
21+ inner : Rc < Inner > ,
2222}
2323
2424#[ derive( Debug , Clone ) ]
2525pub struct Inner {
2626 prerender_service_url : Url ,
2727 inner_client : Client ,
28+ prerender_token : String ,
2829}
2930
3031impl Prerender { }
3132
32- #[ derive( Debug ) ]
33+ #[ derive( Debug , Clone ) ]
3334pub struct PrerenderBuilder { }
3435
3536impl PrerenderBuilder {
36- pub fn use_prerender_io ( mut self ) -> Prerender {
37- Prerender {
37+ pub fn use_prerender_io ( self , token : String ) -> Prerender {
38+ let inner = Inner {
3839 prerender_service_url : prerender_url ( ) ,
39- inner_client : Default :: default ( ) ,
40- }
40+ inner_client : Client :: default ( ) ,
41+ prerender_token : token,
42+ } ;
43+
44+ Prerender { inner : Rc :: new ( inner) }
4145 }
4246
4347 pub fn use_custom_prerender_url (
44- mut self ,
48+ self ,
4549 prerender_service_url : & str ,
50+ token : String ,
4651 ) -> Result < Prerender , PrerenderError > {
47- let result = Url :: parse ( prerender_service_url) . map_err ( |_| PrerenderError :: InvalidUrl ) ?;
52+ let prerender_service_url = Url :: parse ( prerender_service_url) . map_err ( |_| PrerenderError :: InvalidUrl ) ?;
4853
49- Ok ( Prerender {
50- prerender_service_url : result,
51- inner_client : Default :: default ( ) ,
52- } )
54+ let inner = Inner {
55+ prerender_service_url,
56+ inner_client : Client :: default ( ) ,
57+ prerender_token : token,
58+ } ;
59+
60+ Ok ( Prerender { inner : Rc :: new ( inner) } )
5361 }
5462}
5563
5664impl Prerender {
57- pub fn builder ( ) -> PrerenderBuilder {
65+ pub const fn builder ( ) -> PrerenderBuilder {
5866 PrerenderBuilder { }
5967 }
6068}
@@ -98,11 +106,7 @@ pub(crate) fn should_prerender(req: &ServiceRequest) -> bool {
98106 // check for ignored extensions
99107 let is_ignored_extension_url = req. uri ( ) . path_and_query ( ) . map_or_else (
100108 || false ,
101- |path_query| {
102- IGNORED_EXTENSIONS
103- . iter ( )
104- . any ( |ext| path_query. as_str ( ) . contains ( ext) )
105- } ,
109+ |path_query| IGNORED_EXTENSIONS . iter ( ) . any ( |ext| path_query. as_str ( ) . contains ( ext) ) ,
106110 ) ;
107111 if is_ignored_extension_url {
108112 return false ;
@@ -114,44 +118,28 @@ pub(crate) fn should_prerender(req: &ServiceRequest) -> bool {
114118#[ derive( Debug ) ]
115119pub struct PrerenderMiddleware < S > {
116120 pub ( crate ) service : S ,
117- prerender_service_url : Url ,
118- inner_client : Client ,
121+ inner : Rc < Inner > ,
119122}
120123
121124impl < S > PrerenderMiddleware < S > {
122- pub fn prepare_build_api_url ( & self , req : & ServiceRequest ) -> String {
125+ pub fn prepare_build_api_url ( service_url : & Url , req : & ServiceRequest ) -> String {
123126 let req_uri = req. uri ( ) ;
124127 let req_headers = req. headers ( ) ;
125128
126- // TODO: this.host?
127129 let host = req
128130 . uri ( )
129131 . host ( )
130- . or_else ( || {
131- req_headers
132- . get ( "X-Forwarded-Host" )
133- . and_then ( |hdr| hdr. to_str ( ) . ok ( ) )
134- } )
135- . or_else ( || {
136- req_headers
137- . get ( header:: HOST )
138- . and_then ( |hdr| hdr. to_str ( ) . ok ( ) )
139- } )
132+ . or_else ( || req_headers. get ( "X-Forwarded-Host" ) . and_then ( |hdr| hdr. to_str ( ) . ok ( ) ) )
133+ . or_else ( || req_headers. get ( header:: HOST ) . and_then ( |hdr| hdr. to_str ( ) . ok ( ) ) )
140134 . unwrap ( ) ;
141135
142136 let scheme = req. uri ( ) . scheme_str ( ) . unwrap_or ( "http" ) ;
143137 let url_path_query = req_uri. path_and_query ( ) . map ( PathAndQuery :: as_str) . unwrap ( ) ;
144138
145- format ! (
146- "{}{}://{}{}" ,
147- self . prerender_service_url, scheme, host, url_path_query
148- )
139+ format ! ( "{}{}://{}{}" , service_url, scheme, host, url_path_query)
149140 }
150141
151- pub async fn get_rendered_response (
152- & self ,
153- req : ServiceRequest ,
154- ) -> Result < ServiceResponse , PrerenderError > {
142+ pub async fn get_rendered_response ( inner : & Inner , req : ServiceRequest ) -> Result < ServiceResponse , PrerenderError > {
155143 let mut prerender_request_headers = HeaderMap :: new ( ) ;
156144 let forward_headers = true ;
157145
@@ -161,19 +149,20 @@ impl<S> PrerenderMiddleware<S> {
161149 }
162150
163151 prerender_request_headers. append ( header:: ACCEPT_ENCODING , "gzip" . parse ( ) . unwrap ( ) ) ;
152+ prerender_request_headers. append (
153+ "X-Prerender-Token" . parse ( ) . unwrap ( ) ,
154+ inner. prerender_token . parse ( ) . unwrap ( ) ,
155+ ) ;
164156
165- // TODO: accept `X-Prerender-Token`
166- // prerender_request_headers.insert("X-Prerender-Token", pre_render_token);
167-
168- let url_to_request = self . prepare_build_api_url ( & req) ;
169- let prerender_response = self
157+ let url_to_request = Self :: prepare_build_api_url ( & inner. prerender_service_url , & req) ;
158+ let prerender_response = inner
170159 . inner_client
171160 . get ( url_to_request)
172161 . send ( )
173- . and_then ( |a| a . bytes ( ) )
162+ . and_then ( |resp| resp . bytes ( ) )
174163 . await ?;
175164
176- let http_response = HttpResponse :: Ok ( ) . body ( prerender_response) ;
165+ let http_response = HttpResponse :: Ok ( ) . content_type ( "text/html" ) . body ( prerender_response) ;
177166 Ok ( req. into_response ( http_response) )
178167 }
179168}
@@ -196,8 +185,8 @@ where
196185 return Box :: pin ( async move { fut. await } ) ;
197186 }
198187
199- // let response = self.get_rendered_response(req).await.map_err(|e| );
200- todo ! ( )
188+ let inner = Rc :: clone ( & self . inner ) ;
189+ Box :: pin ( async move { Self :: get_rendered_response ( & inner , req ) . await . map_err ( Into :: into ) } )
201190 }
202191}
203192
@@ -215,27 +204,28 @@ where
215204 fn new_transform ( & self , service : S ) -> Self :: Future {
216205 future:: ok ( PrerenderMiddleware {
217206 service,
218- prerender_service_url : self . prerender_service_url . clone ( ) ,
219- inner_client : self . inner_client . clone ( ) ,
207+ inner : Rc :: clone ( & self . inner ) ,
220208 } )
221209 }
222210}
223211
224212#[ cfg( test) ]
225213mod tests {
226- use crate :: middleware:: { prerender_url, should_prerender, Prerender , PrerenderMiddleware } ;
227- use actix_service:: Transform ;
214+
228215 use actix_web:: http:: header;
229216 use actix_web:: middleware:: Compat ;
230217 use actix_web:: test:: TestRequest ;
231- use actix_web:: { test, App } ;
218+ use actix_web:: App ;
219+
220+ use crate :: middleware:: { prerender_url, should_prerender, Prerender , PrerenderMiddleware } ;
232221
233- fn init_logger ( ) {
222+ fn _init_logger ( ) {
234223 let _ = env_logger:: builder ( ) . is_test ( true ) . try_init ( ) ;
235224 }
236225
237- fn compat_compat ( ) {
238- let _ = App :: new ( ) . wrap ( Compat :: new ( Prerender :: builder ( ) . use_prerender_io ( ) ) ) ;
226+ #[ actix_web:: test]
227+ async fn compat_compat ( ) {
228+ App :: new ( ) . wrap ( Compat :: new ( Prerender :: builder ( ) . use_prerender_io ( "" . to_string ( ) ) ) ) ;
239229 }
240230
241231 #[ actix_web:: test]
@@ -292,8 +282,8 @@ mod tests {
292282 assert ! ( !render) ;
293283 }
294284
295- fn create_middleware ( ) -> Prerender {
296- Prerender :: builder ( ) . use_prerender_io ( )
285+ fn _create_middleware ( ) -> Prerender {
286+ Prerender :: builder ( ) . use_prerender_io ( "" . to_string ( ) )
297287 }
298288
299289 #[ actix_web:: test]
@@ -308,13 +298,13 @@ mod tests {
308298 . uri ( req_url)
309299 . to_srv_request ( ) ;
310300
311- let middleware = create_middleware ( )
312- . new_transform ( test:: ok_service ( ) )
313- . into_inner ( )
314- . unwrap ( ) ;
301+ // let middleware = create_middleware()
302+ // .new_transform(test::ok_service())
303+ // .into_inner()
304+ // .unwrap();
315305
316306 assert_eq ! (
317- middleware . prepare_build_api_url( & req) ,
307+ PrerenderMiddleware :: < ( ) > :: prepare_build_api_url( & prerender_url ( ) , & req) ,
318308 format!( "{}{}" , prerender_url( ) , req_url)
319309 ) ;
320310 }
0 commit comments