66// option. All files in the project carrying such notice may not be copied,
77// modified, or distributed except according to those terms.
88
9+ use BoxFuture ;
10+ use lib_futures:: { Future , IntoFuture , oneshot} ;
911use std:: fs;
1012use std:: io:: { self , Read } ;
1113use mio:: { Evented , Poll , PollOpt , Ready , Registration , Token } ;
@@ -16,7 +18,7 @@ use errors::*;
1618use std:: collections:: HashSet ;
1719use std:: str:: from_utf8;
1820use super :: LocalInfileHandler ;
19- use tokio:: reactor:: { Handle , PollEvented } ;
21+ use tokio:: reactor:: { Handle , Remote , PollEvented } ;
2022use tokio_io:: AsyncRead ;
2123
2224#[ derive( Debug ) ]
@@ -163,7 +165,7 @@ impl Evented for File {
163165#[ derive( Clone , Debug ) ]
164166pub struct WhiteListFsLocalInfileHandler {
165167 white_list : HashSet < PathBuf > ,
166- handle : Handle ,
168+ handle : Remote ,
167169}
168170
169171impl WhiteListFsLocalInfileHandler {
@@ -176,22 +178,45 @@ impl WhiteListFsLocalInfileHandler {
176178 for path in white_list. into_iter ( ) {
177179 white_list_set. insert ( Into :: < PathBuf > :: into ( path) ) ;
178180 }
179- WhiteListFsLocalInfileHandler { white_list : white_list_set, handle : handle. clone ( ) }
181+ WhiteListFsLocalInfileHandler {
182+ white_list : white_list_set,
183+ handle : handle. remote ( ) . clone ( ) ,
184+ }
180185 }
181186}
182187
183188impl LocalInfileHandler for WhiteListFsLocalInfileHandler {
184- fn handle ( & self , file_name : & [ u8 ] ) -> Result < Box < AsyncRead > > {
189+ fn handle ( & self , file_name : & [ u8 ] ) -> BoxFuture < Box < AsyncRead > > {
185190 let path: PathBuf = match from_utf8 ( file_name) {
186191 Ok ( path_str) => path_str. into ( ) ,
187- Err ( _) => bail ! ( "Invalid file name" ) ,
192+ Err ( _) => return Box :: new ( Err ( "Invalid file name" . into ( ) ) . into_future ( ) ) ,
188193 } ;
189194 if self . white_list . contains ( & path) {
190- Ok ( Box :: new (
191- PollEvented :: new ( File :: new ( path) , & self . handle ) ?,
192- ) as Box < AsyncRead > )
195+ match self . handle . handle ( ) {
196+ Some ( handle) => {
197+ let fut = PollEvented :: new ( File :: new ( path) , & handle)
198+ . map_err ( Into :: into)
199+ . map ( |poll_evented| Box :: new ( poll_evented) as Box < AsyncRead > )
200+ . into_future ( ) ;
201+ Box :: new ( fut) as BoxFuture < Box < AsyncRead > >
202+ } ,
203+ None => {
204+ let ( tx, rx) = oneshot ( ) ;
205+ self . handle . spawn ( |handle| {
206+ let poll_evented_res = PollEvented :: new ( File :: new ( path) , & handle) ;
207+ let _ = tx. send ( poll_evented_res. map_err ( Error :: from) ) ;
208+ Ok ( ( ) )
209+ } ) ;
210+ let fut = rx
211+ . map_err ( |_| Error :: from ( "Future Canceled" ) )
212+ . and_then ( |r| r. into_future ( ) )
213+ . map ( |poll_evented| Box :: new ( poll_evented) as Box < AsyncRead > ) ;
214+ Box :: new ( fut) as BoxFuture < Box < AsyncRead > >
215+ }
216+ }
193217 } else {
194- bail ! ( format!( "Path `{}' is not in white list" , path. display( ) ) ) ;
218+ let err_msg = format ! ( "Path `{}' is not in white list" , path. display( ) ) ;
219+ return Box :: new ( Err ( err_msg. into ( ) ) . into_future ( ) ) ;
195220 }
196221 }
197222}
0 commit comments