2121import org .springframework .http .ResponseEntity ;
2222import org .springframework .stereotype .Controller ;
2323import org .springframework .web .bind .annotation .GetMapping ;
24+ import org .springframework .web .bind .annotation .PostMapping ;
25+ import org .springframework .web .bind .annotation .RequestBody ;
2426import org .springframework .web .bind .annotation .PathVariable ;
27+ import org .springframework .web .bind .annotation .RequestHeader ;
2528import org .springframework .web .bind .annotation .RequestMapping ;
2629import org .springframework .web .bind .annotation .ResponseBody ;
2730
31+ import java .nio .file .Files ;
32+ import java .nio .file .Paths ;
33+ import java .nio .file .Path ;
34+ import java .util .List ;
35+ import java .util .Map ;
36+
37+ import org .springframework .boot .SpringApplication ;
38+ import org .springframework .context .ApplicationContext ;
39+ import org .springframework .http .HttpHeaders ;
40+ import org .springframework .http .HttpStatus ;
41+ import org .springframework .http .MediaType ;
42+
2843@ Controller
2944@ RequestMapping ("/utility" )
3045public class UtilityController {
3146
47+ private final ApplicationContext context ;
48+
49+ public UtilityController (ApplicationContext context ) {
50+ this .context = context ;
51+ }
52+
3253 @ GetMapping ("/stress/{iterations}" )
3354 @ ResponseBody
3455 public double stress (@ PathVariable int iterations ) {
@@ -51,4 +72,75 @@ private double monteCarloPi(int iterations) {
5172 public ResponseEntity <String > status (@ PathVariable int code ) {
5273 return ResponseEntity .status (code ).body ("OK" );
5374 }
75+
76+ @ GetMapping (value = "/headers" , produces = MediaType .APPLICATION_JSON_VALUE )
77+ public ResponseEntity <Map <String , List <String >>> statusHeaders (@ RequestHeader HttpHeaders headers ) {
78+ return ResponseEntity .ok ()
79+ .body (headers );
80+ }
81+
82+ @ GetMapping ("/panic" )
83+ public ResponseEntity <String > panic () {
84+ Thread thread = new Thread (() -> {
85+ try {
86+ Thread .sleep (500 ); // Small delay to allow response to be sent
87+ SpringApplication .exit (context , () -> 1 );
88+ System .exit (255 );
89+ } catch (InterruptedException e ) {
90+ Thread .currentThread ().interrupt ();
91+ }
92+ });
93+ thread .start ();
94+ return ResponseEntity .status (HttpStatus .INTERNAL_SERVER_ERROR ).body ("Shutting down..." );
95+ }
96+
97+ // function /echo that answer the hash provided as POST input
98+ @ PostMapping ("/echo" )
99+ @ ResponseBody
100+ public ResponseEntity <String > echo (@ RequestBody String body ) {
101+ return ResponseEntity .ok ()
102+ .body (body );
103+ }
104+
105+ // function /store what take a POST hash to write to a locally created file
106+ @ PostMapping ("/store" )
107+ @ ResponseBody
108+ public ResponseEntity <String > store (@ RequestBody String body ) {
109+ String filename = String .valueOf (Math .abs (body .hashCode ())); // ensure positive number
110+ try (java .io .FileWriter fileWriter = new java .io .FileWriter ("/tmp/" + filename + ".json" )) {
111+ fileWriter .write (body );
112+ return ResponseEntity .ok ()
113+ .body ("{\" hash\" : \" " + filename + "\" }" );
114+ } catch (Exception e ) {
115+ return ResponseEntity .status (HttpStatus .INTERNAL_SERVER_ERROR )
116+ .body ("Error writing file: " + e .getMessage ());
117+ }
118+ }
119+
120+ // function /store/{hash} that read a local hash file
121+ @ GetMapping ("/store/{hash}" )
122+ @ ResponseBody
123+ public ResponseEntity <String > store_hash (@ PathVariable String hash ) {
124+ // Validate hash format - only allow numeric characters
125+ if (!hash .matches ("^[0-9]+$" )) {
126+ return ResponseEntity .badRequest ()
127+ .body ("Invalid hash format" );
128+ }
129+
130+ // Normalize the path and verify it's within the intended directory
131+ Path filePath = Paths .get ("/tmp" , hash + ".json" ).normalize ();
132+ if (!filePath .startsWith ("/tmp/" )) {
133+ return ResponseEntity .badRequest ()
134+ .body ("Invalid path" );
135+ }
136+
137+ try {
138+ String body = new String (Files .readAllBytes (filePath ));
139+ return ResponseEntity .ok ()
140+ .body (body );
141+ } catch (Exception e ) {
142+ return ResponseEntity .status (HttpStatus .NOT_FOUND )
143+ .body ("Error reading file: " + e .getMessage ());
144+ }
145+ }
54146}
0 commit comments