@@ -5,7 +5,8 @@ use actix_web_httpauth::middleware::HttpAuthentication;
55use std:: env;
66use std:: fs:: OpenOptions ;
77use std:: io:: { BufReader , BufWriter } ;
8- use std:: sync:: { Arc , Mutex } ;
8+ use std:: path:: { Component , Path , PathBuf } ;
9+ use std:: sync:: Arc ;
910use structopt:: StructOpt ;
1011
1112fn read_results ( file_name : & str ) -> Vec < String > {
@@ -54,7 +55,7 @@ fn get(file_name: &str) -> std::io::Result<Option<String>> {
5455
5556#[ derive( Clone ) ]
5657struct AppState {
57- lock : Arc < Mutex < ( ) > > ,
58+ lock : Arc < tokio :: sync :: Mutex < ( ) > > ,
5859 file_name : String ,
5960}
6061
@@ -83,7 +84,7 @@ pub struct CliOptions {
8384}
8485
8586async fn add_to_queue ( data : web:: Data < AppState > , item : String ) -> impl Responder {
86- let _lock = data. lock . lock ( ) . unwrap ( ) ;
87+ let _lock = data. lock . lock ( ) . await ;
8788 let Ok ( private_key) = hex:: decode ( item. replace ( "0x" , "" ) ) else {
8889 return HttpResponse :: BadRequest ( ) . body ( "Invalid item type" ) ;
8990 } ;
@@ -101,14 +102,14 @@ async fn add_to_queue(data: web::Data<AppState>, item: String) -> impl Responder
101102}
102103
103104async fn count ( data : web:: Data < AppState > ) -> impl Responder {
104- let _lock = data. lock . lock ( ) . unwrap ( ) ;
105+ let _lock = data. lock . lock ( ) . await ;
105106 let file_name = & data. file_name ;
106107 let results = read_results ( file_name) ;
107108 HttpResponse :: Ok ( ) . body ( results. len ( ) . to_string ( ) )
108109}
109110
110111async fn get_from_queue ( data : web:: Data < AppState > ) -> impl Responder {
111- let _lock = data. lock . lock ( ) . unwrap ( ) ;
112+ let _lock = data. lock . lock ( ) . await ;
112113 match get ( & data. file_name ) {
113114 Ok ( Some ( item) ) => HttpResponse :: Ok ( ) . body ( item) ,
114115 Ok ( None ) => HttpResponse :: BadRequest ( ) . body ( "Queue is empty" ) ,
@@ -119,6 +120,70 @@ async fn get_from_queue(data: web::Data<AppState>) -> impl Responder {
119120 }
120121}
121122
123+ fn get_file_name_from_filename_and_group ( file_name : & str , group : & str ) -> String {
124+ let sanitized_group: String = group
125+ . chars ( )
126+ . filter ( |c| c. is_alphanumeric ( ) || * c == '_' ) // Allow only alphanumeric and underscores
127+ . collect ( ) ;
128+
129+ let sanitized_file_name = Path :: new ( file_name)
130+ . components ( )
131+ . filter ( |comp| matches ! ( comp, Component :: Normal ( _) ) ) // Allow only valid file names
132+ . collect :: < PathBuf > ( ) ;
133+
134+ format ! ( "{}_{}" , sanitized_group, sanitized_file_name. display( ) )
135+ }
136+
137+ async fn add_to_queue_group (
138+ data : web:: Data < AppState > ,
139+ path : web:: Path < String > ,
140+ item : String ,
141+ ) -> impl Responder {
142+ let _lock = data. lock . lock ( ) . await ;
143+ let group = path. into_inner ( ) ;
144+ let file_name = get_file_name_from_filename_and_group ( & data. file_name , & group) ;
145+ let Ok ( private_key) = hex:: decode ( item. replace ( "0x" , "" ) ) else {
146+ return HttpResponse :: BadRequest ( ) . body ( "Invalid item type" ) ;
147+ } ;
148+ if private_key. len ( ) != 32 {
149+ return HttpResponse :: BadRequest ( ) . body ( "Invalid item length" ) ;
150+ }
151+ match add ( hex:: encode ( private_key) , & file_name) {
152+ Ok ( true ) => HttpResponse :: Ok ( ) . body ( "Added to the queue" ) ,
153+ Ok ( false ) => HttpResponse :: Ok ( ) . body ( "Item already in the queue" ) ,
154+ Err ( e) => {
155+ log:: error!( "Error adding item: {}" , e) ;
156+ HttpResponse :: InternalServerError ( ) . finish ( )
157+ }
158+ }
159+ }
160+
161+ async fn count_group ( data : web:: Data < AppState > , path : web:: Path < String > ) -> impl Responder {
162+ let _lock = data. lock . lock ( ) . await ;
163+ let group = path. into_inner ( ) ;
164+ let file_name = get_file_name_from_filename_and_group ( & data. file_name , & group) ;
165+ let results = read_results ( & file_name) ;
166+ HttpResponse :: Ok ( ) . body ( results. len ( ) . to_string ( ) )
167+ }
168+
169+ async fn get_from_queue_group (
170+ data : web:: Data < AppState > ,
171+ path : web:: Path < String > ,
172+ ) -> impl Responder {
173+ let _lock = data. lock . lock ( ) . await ;
174+
175+ let group = path. into_inner ( ) ;
176+ let file_name = get_file_name_from_filename_and_group ( & data. file_name , & group) ;
177+ match get ( & file_name) {
178+ Ok ( Some ( item) ) => HttpResponse :: Ok ( ) . body ( item) ,
179+ Ok ( None ) => HttpResponse :: BadRequest ( ) . body ( "Queue is empty" ) ,
180+ Err ( e) => {
181+ log:: error!( "Error getting item: {}" , e) ;
182+ HttpResponse :: InternalServerError ( ) . finish ( )
183+ }
184+ }
185+ }
186+
122187fn get_env_access_token ( ) -> String {
123188 env:: var ( "BEARER_KEY" ) . unwrap_or ( "change_me" . to_string ( ) )
124189}
@@ -152,7 +217,7 @@ async fn main() -> std::io::Result<()> {
152217 // Load the queue from file or create a new one
153218
154219 let app_state = AppState {
155- lock : Arc :: new ( Mutex :: new ( ( ) ) ) ,
220+ lock : Arc :: new ( tokio :: sync :: Mutex :: new ( ( ) ) ) ,
156221 file_name : args. file_name ,
157222 } ;
158223
@@ -167,6 +232,9 @@ async fn main() -> std::io::Result<()> {
167232 . route ( "/count" , web:: get ( ) . to ( count) )
168233 . route ( "/add" , web:: post ( ) . to ( add_to_queue) )
169234 . route ( "/get" , web:: get ( ) . to ( get_from_queue) )
235+ . route ( "/count/{group}" , web:: get ( ) . to ( count_group) )
236+ . route ( "/add/{group}" , web:: post ( ) . to ( add_to_queue_group) )
237+ . route ( "/get/{group}" , web:: get ( ) . to ( get_from_queue_group) )
170238 } )
171239 . bind ( format ! ( "{}:{}" , args. http_addr, args. http_port) ) ?
172240 . workers ( 1 )
0 commit comments