@@ -115,55 +115,64 @@ async fn serve_gcs_content(
115115 } else {
116116 Some ( format ! ( "{}/" , path_str. trim_end_matches( '/' ) ) )
117117 } ;
118-
119- let list_req = ListObjectsRequest {
120- bucket : bucket_name. clone ( ) ,
121- prefix,
122- delimiter : Some ( "/" . to_string ( ) ) ,
123- max_results : Some ( 10000 ) ,
124- ..Default :: default ( )
125- } ;
126-
127- let objects = match client. list_objects ( & list_req) . await {
128- Ok ( objects) => objects,
129- Err ( e) => {
130- eprintln ! ( "Error listing objects: {:?}" , e) ;
131- return Ok ( Response :: builder ( )
132- . status ( 500 )
133- . body ( "Error listing content" . as_bytes ( ) . to_vec ( ) )
134- . unwrap ( ) ) ;
135- }
136- } ;
137-
138118 let mut folders = Vec :: new ( ) ;
139119 let mut files = Vec :: new ( ) ;
140- if let Some ( prefixes) = objects. prefixes {
141- for prefix in prefixes {
142- folders. push ( prefix) ;
120+ let mut next_page_token: Option < String > = None ;
121+
122+ // Currently we have folders with 10,000 files. So we have to loop this till we have
123+ // no more page tokens.
124+ loop {
125+ let list_req = ListObjectsRequest {
126+ bucket : bucket_name. clone ( ) ,
127+ prefix : prefix. clone ( ) ,
128+ delimiter : Some ( "/" . to_string ( ) ) ,
129+ max_results : Some ( 2500 ) ,
130+ page_token : next_page_token,
131+ ..Default :: default ( )
132+ } ;
133+ let objects = match client. list_objects ( & list_req) . await {
134+ Ok ( objects) => objects,
135+ Err ( e) => {
136+ eprintln ! ( "Error listing objects: {:?}" , e) ;
137+ return Ok ( Response :: builder ( )
138+ . status ( 500 )
139+ . body ( "Error listing content" . as_bytes ( ) . to_vec ( ) )
140+ . unwrap ( ) ) ;
141+ }
142+ } ;
143+ if objects. prefixes . is_some ( ) && list_req. page_token . is_none ( ) {
144+ for prefix in objects. prefixes . unwrap ( ) {
145+ folders. push ( prefix) ;
146+ }
143147 }
144- }
145- if let Some ( items) = objects. items {
146- for item in items {
147- // Do not include the directory itself in the file list
148- if item. name != path_str {
149- let size = item. size ;
150- let filesize: String ;
151- if size > 1048576 {
152- filesize = format ! ( "{}M" , ( size as f64 / 1048576 as f64 ) . round( ) )
153- } else if size > 1024 {
154- filesize = format ! ( "{}K" , ( size as f64 / 1024 as f64 ) . round( ) )
155- } else {
156- filesize = format ! ( "{}" , size)
157- }
158- if let Some ( updated) = item. updated {
159- let format =
160- format_description:: parse ( "[year]-[month]-[day] [hour]:[minute]" )
161- . unwrap ( ) ;
162- let u = updated. format ( & format) . unwrap ( ) ;
163- files. push ( ( item. name , filesize, u) ) ;
148+
149+ if let Some ( items) = objects. items {
150+ for item in items {
151+ // Do not include the directory itself in the file list
152+ if item. name != path_str {
153+ let size = item. size ;
154+ let filesize: String ;
155+ if size > 1048576 {
156+ filesize = format ! ( "{}M" , ( size as f64 / 1048576 as f64 ) . round( ) )
157+ } else if size > 1024 {
158+ filesize = format ! ( "{}K" , ( size as f64 / 1024 as f64 ) . round( ) )
159+ } else {
160+ filesize = format ! ( "{}" , size)
161+ }
162+ if let Some ( updated) = item. updated {
163+ let format =
164+ format_description:: parse ( "[year]-[month]-[day] [hour]:[minute]" )
165+ . unwrap ( ) ;
166+ let u = updated. format ( & format) . unwrap ( ) ;
167+ files. push ( ( item. name , filesize, u) ) ;
168+ }
164169 }
165170 }
166171 }
172+ if objects. next_page_token . is_none ( ) {
173+ break ;
174+ }
175+ next_page_token = objects. next_page_token ;
167176 }
168177
169178 let html = build_html ( path_str, folders, files) ;
0 commit comments