@@ -56,6 +56,7 @@ type Server struct {
5656 host string
5757 address string
5858
59+ shutDown bool
5960 saveFileName string
6061 useCustomLogger bool
6162 logFileName string
@@ -203,8 +204,8 @@ func Wake(options ...ServerOption) (*Server, error) {
203204 }
204205
205206 mux := http .NewServeMux ()
206- mux . HandleFunc ( "/register" , p . registerRouteHandler )
207- mux .HandleFunc ("/record " , p .recordHandler )
207+ // TODO: Add a route to
208+ mux .HandleFunc ("/routes " , p .routesHandler )
208209 mux .HandleFunc ("/" , p .dynamicHandler )
209210
210211 p .server = & http.Server {
@@ -241,6 +242,7 @@ func (p *Server) run(listener net.Listener) {
241242
242243// Shutdown gracefully shuts down the parrot server
243244func (p * Server ) Shutdown (ctx context.Context ) error {
245+ p .shutDown = true
244246 p .log .Info ().Msg ("Putting cloth over the parrot's cage..." )
245247 return p .server .Shutdown (ctx )
246248}
@@ -301,64 +303,86 @@ func (p *Server) Register(route *Route) error {
301303 return nil
302304}
303305
304- // registerRouteHandler handles the dynamic route registration.
305- func (p * Server ) registerRouteHandler (w http.ResponseWriter , r * http.Request ) {
306- registerLogger := zerolog .Ctx (r .Context ())
306+ // routesHandler handles the dynamic route registration.
307+ func (p * Server ) routesHandler (w http.ResponseWriter , r * http.Request ) {
308+ routesLogger := zerolog .Ctx (r .Context ())
307309 if r .Method == http .MethodDelete {
308310 var routeRequest * RouteRequest
309311 if err := json .NewDecoder (r .Body ).Decode (& routeRequest ); err != nil {
310312 http .Error (w , "Invalid request body" , http .StatusBadRequest )
311- registerLogger .Debug ().Err (err ).Msg ("Failed to decode request body" )
313+ routesLogger .Debug ().Err (err ).Msg ("Failed to decode request body" )
312314 return
313315 }
314316 defer r .Body .Close ()
315317
316318 if routeRequest .ID == "" {
317319 http .Error (w , "Route ID required" , http .StatusBadRequest )
318- registerLogger .Debug ().Msg ("No Route ID provided" )
320+ routesLogger .Debug ().Msg ("No Route ID provided" )
319321 return
320322 }
321323
322324 err := p .Unregister (routeRequest .ID )
323325 if err != nil {
324326 http .Error (w , err .Error (), http .StatusBadRequest )
325- registerLogger .Debug ().Err (err ).Msg ("Failed to unregister route" )
327+ routesLogger .Debug ().Err (err ).Msg ("Failed to unregister route" )
326328 return
327329 }
328330
329331 w .WriteHeader (http .StatusNoContent )
330- registerLogger .Info ().
332+ routesLogger .Info ().
331333 Str ("Route ID" , routeRequest .ID ).
332334 Msg ("Route unregistered" )
333- } else if r .Method == http .MethodPost {
335+ return
336+ }
337+
338+ if r .Method == http .MethodPost {
334339 var route * Route
335340 if err := json .NewDecoder (r .Body ).Decode (& route ); err != nil {
336341 http .Error (w , "Invalid request body" , http .StatusBadRequest )
337- registerLogger .Debug ().Err (err ).Msg ("Failed to decode request body" )
342+ routesLogger .Debug ().Err (err ).Msg ("Failed to decode request body" )
338343 return
339344 }
340345 defer r .Body .Close ()
341346
342347 if route .Method == "" || route .Path == "" {
343348 err := errors .New ("Method and path are required" )
344349 http .Error (w , err .Error (), http .StatusBadRequest )
345- registerLogger .Debug ().Err (err ).Msg ("Method and path are required" )
350+ routesLogger .Debug ().Err (err ).Msg ("Method and path are required" )
346351 return
347352 }
348353
349354 err := p .Register (route )
350355 if err != nil {
351356 http .Error (w , err .Error (), http .StatusBadRequest )
352- registerLogger .Debug ().Err (err ).Msg ("Failed to register route" )
357+ routesLogger .Debug ().Err (err ).Msg ("Failed to register route" )
353358 return
354359 }
355360
356361 w .WriteHeader (http .StatusCreated )
357- } else {
358- http .Error (w , "Invalid method, only use POST or DELETE" , http .StatusMethodNotAllowed )
359- registerLogger .Debug ().Msg ("Invalid method" )
360362 return
361363 }
364+
365+ if r .Method == http .MethodGet {
366+ jsonRoutes , err := json .Marshal (p .Routes ())
367+ if err != nil {
368+ http .Error (w , "Failed to marshal routes" , http .StatusInternalServerError )
369+ routesLogger .Debug ().Err (err ).Msg ("Failed to marshal routes" )
370+ return
371+ }
372+
373+ w .Header ().Set ("Content-Type" , "application/json" )
374+ if _ , err = w .Write (jsonRoutes ); err != nil {
375+ http .Error (w , "Failed to write response" , http .StatusInternalServerError )
376+ routesLogger .Debug ().Err (err ).Msg ("Failed to write response" )
377+ return
378+ }
379+
380+ routesLogger .Debug ().Msg ("Returned routes" )
381+ return
382+ }
383+
384+ http .Error (w , "Invalid method" , http .StatusMethodNotAllowed )
385+ routesLogger .Debug ().Msg ("Invalid method" )
362386}
363387
364388// Record registers a new recorder with the parrot. All incoming requests to the parrot will be sent to the recorder.
@@ -376,32 +400,6 @@ func (p *Server) Record(recorderURL string) error {
376400 return nil
377401}
378402
379- func (p * Server ) recordHandler (w http.ResponseWriter , r * http.Request ) {
380- recordLogger := zerolog .Ctx (r .Context ())
381- if r .Method != http .MethodPost {
382- http .Error (w , "Invalid method, only use POST or DELETE" , http .StatusMethodNotAllowed )
383- recordLogger .Debug ().Msg ("Invalid method" )
384- return
385- }
386-
387- var recorder * Recorder
388- if err := json .NewDecoder (r .Body ).Decode (& recorder ); err != nil {
389- http .Error (w , "Invalid request body" , http .StatusBadRequest )
390- recordLogger .Err (err ).Msg ("Failed to decode request body" )
391- return
392- }
393-
394- err := p .Record (recorder .URL )
395- if err != nil {
396- http .Error (w , err .Error (), http .StatusBadRequest )
397- recordLogger .Debug ().Err (err ).Msg ("Failed to add recorder" )
398- return
399- }
400-
401- w .WriteHeader (http .StatusCreated )
402- recordLogger .Info ().Str ("Recorder URL" , recorder .URL ).Msg ("Recorder added" )
403- }
404-
405403// Unregister removes a route from the parrot
406404func (p * Server ) Unregister (routeID string ) error {
407405 p .routesMu .RLock ()
@@ -428,6 +426,17 @@ func (p *Server) Call(method, path string) (*http.Response, error) {
428426 return client .Do (req )
429427}
430428
429+ func (p * Server ) Routes () []* Route {
430+ p .routesMu .RLock ()
431+ defer p .routesMu .RUnlock ()
432+
433+ routes := make ([]* Route , 0 , len (p .routes ))
434+ for _ , route := range p .routes {
435+ routes = append (routes , route )
436+ }
437+ return routes
438+ }
439+
431440// dynamicHandler handles all incoming requests and responds based on the registered routes.
432441func (p * Server ) dynamicHandler (w http.ResponseWriter , r * http.Request ) {
433442 p .routesMu .RLock ()
0 commit comments