From 0613222b4bb21f7083b5059ccbedd470936d56cb Mon Sep 17 00:00:00 2001 From: Fabricio Date: Thu, 20 Jun 2019 20:09:58 -0300 Subject: [PATCH] give better names to stuff --- capture.go | 112 +++++++++++++++++++++++++---------------------------- main.go | 40 +++++++++---------- 2 files changed, 73 insertions(+), 79 deletions(-) diff --git a/capture.go b/capture.go index 27aa9b8..6cff8c8 100644 --- a/capture.go +++ b/capture.go @@ -9,26 +9,25 @@ import ( var captureID int -// CaptureList stores all captures -type CaptureList struct { +// CaptureService handles captures +type CaptureService struct { items []Capture mu sync.RWMutex maxItems int updated chan struct{} // signals any change in "items" } -// Capture saves our traffic data +// Capture is our traffic data type Capture struct { ID int Req *http.Request Res *http.Response - // Elapsed time of the request, in milliseconds Elapsed time.Duration } -// CaptureMetadata is the data for each list item in the dashboard -type CaptureMetadata struct { +// DashboardItem is an item in the dashboard's list +type DashboardItem struct { ID int `json:"id"` Path string `json:"path"` Method string `json:"method"` @@ -37,51 +36,42 @@ type CaptureMetadata struct { Elapsed time.Duration `json:"elapsed"` } -// CaptureDump saves all the dumps shown in the dashboard +// CaptureDump is all the dumps shown in the dashboard type CaptureDump struct { Request string `json:"request"` Response string `json:"response"` Curl string `json:"curl"` } -// Metadata returns the metadada of a capture -func (c *Capture) Metadata() CaptureMetadata { - return CaptureMetadata{ - ID: c.ID, - Path: c.Req.URL.Path, - Method: c.Req.Method, - Status: c.Res.StatusCode, - Elapsed: c.Elapsed, - } -} - -// NewCaptureList creates a new list of captures -func NewCaptureList(maxItems int) *CaptureList { - return &CaptureList{ +// NewCaptureService creates a new service of captures +func NewCaptureService(maxItems int) *CaptureService { + return &CaptureService{ maxItems: maxItems, updated: make(chan struct{}), } } -// Insert adds a new capture -func (c *CaptureList) Insert(capture Capture) { - c.mu.Lock() - defer c.mu.Unlock() +// Insert inserts a new capture +func (s *CaptureService) Insert(capture Capture) { + s.mu.Lock() + defer s.mu.Unlock() + captureID++ capture.ID = captureID - c.items = append(c.items, capture) - if len(c.items) > c.maxItems { - c.items = c.items[1:] + s.items = append(s.items, capture) + if len(s.items) > s.maxItems { + s.items = s.items[1:] } - c.signalsChange() + s.signalsUpdate() } // Find finds a capture by its id -func (c *CaptureList) Find(captureID string) *Capture { - c.mu.RLock() - defer c.mu.RUnlock() +func (s *CaptureService) Find(captureID string) *Capture { + s.mu.RLock() + defer s.mu.RUnlock() + idInt, _ := strconv.Atoi(captureID) - for _, c := range c.items { + for _, c := range s.items { if c.ID == idInt { return &c } @@ -90,39 +80,43 @@ func (c *CaptureList) Find(captureID string) *Capture { } // RemoveAll removes all the captures -func (c *CaptureList) RemoveAll() { - c.mu.Lock() - defer c.mu.Unlock() - c.items = nil - c.signalsChange() +func (s *CaptureService) RemoveAll() { + s.mu.Lock() + defer s.mu.Unlock() + + s.items = nil + s.signalsUpdate() } -// Items returns all the captures -func (c *CaptureList) Items() []Capture { - c.mu.RLock() - defer c.mu.RUnlock() - return c.items -} +// DashboardItems returns the dashboard's list of items +func (s *CaptureService) DashboardItems() []DashboardItem { + s.mu.RLock() + defer s.mu.RUnlock() -// ItemsAsMetadata returns all the captures as metadata -func (c *CaptureList) ItemsAsMetadata() []CaptureMetadata { - c.mu.RLock() - defer c.mu.RUnlock() - metadatas := make([]CaptureMetadata, len(c.items)) - for i, capture := range c.items { - metadatas[i] = capture.Metadata() + metadatas := make([]DashboardItem, len(s.items)) + for i, capture := range s.items { + metadatas[i] = DashboardItem{ + ID: capture.ID, + Path: capture.Req.URL.Path, + Method: capture.Req.Method, + Status: capture.Res.StatusCode, + Elapsed: capture.Elapsed, + } } return metadatas } -func (c *CaptureList) signalsChange() { - close(c.updated) - c.updated = make(chan struct{}) +// signalsUpdate fires an update signal +func (s *CaptureService) signalsUpdate() { + close(s.updated) + s.updated = make(chan struct{}) } -// Updated signals any change in the list -func (c *CaptureList) Updated() <-chan struct{} { - c.mu.RLock() - defer c.mu.RUnlock() - return c.updated +// Updated signals any change in this service, +// like inserting or removing captures +func (s *CaptureService) Updated() <-chan struct{} { + s.mu.RLock() + defer s.mu.RUnlock() + + return s.updated } diff --git a/main.go b/main.go index 3165cfa..5d57160 100644 --- a/main.go +++ b/main.go @@ -31,15 +31,15 @@ func main() { func startCapture(config Config) { - list := NewCaptureList(config.MaxCaptures) + srv := NewCaptureService(config.MaxCaptures) - handler := NewRecorder(list, NewPlugin(NewProxyHandler(config.TargetURL))) + handler := NewRecorderHandler(srv, NewPluginHandler(NewProxyHandler(config.TargetURL))) http.HandleFunc(config.DashboardPath, NewDashboardHTMLHandler(config)) - http.HandleFunc(config.DashboardConnPath, NewDashboardConnHandler(list)) - http.HandleFunc(config.DashboardInfoPath, NewDashboardInfoHandler(list)) - http.HandleFunc(config.DashboardClearPath, NewDashboardClearHandler(list)) - http.HandleFunc(config.DashboardRetryPath, NewDashboardRetryHandler(list, handler)) + http.HandleFunc(config.DashboardConnPath, NewDashboardConnHandler(srv)) + http.HandleFunc(config.DashboardInfoPath, NewDashboardInfoHandler(srv)) + http.HandleFunc(config.DashboardClearPath, NewDashboardClearHandler(srv)) + http.HandleFunc(config.DashboardRetryPath, NewDashboardRetryHandler(srv, handler)) http.HandleFunc("/", handler) captureHost := fmt.Sprintf("http://localhost:%s", config.ProxyPort) @@ -52,7 +52,7 @@ func startCapture(config Config) { // NewDashboardConnHandler opens an event stream connection with the dashboard // so that it is notified everytime a new capture arrives -func NewDashboardConnHandler(list *CaptureList) http.HandlerFunc { +func NewDashboardConnHandler(srv *CaptureService) http.HandlerFunc { return func(rw http.ResponseWriter, req *http.Request) { if _, ok := rw.(http.Flusher); !ok { fmt.Printf("streaming not supported at %s\n", req.URL) @@ -62,12 +62,12 @@ func NewDashboardConnHandler(list *CaptureList) http.HandlerFunc { rw.Header().Set("Content-Type", "text/event-stream") rw.Header().Set("Cache-Control", "no-cache") for { - jsn, _ := json.Marshal(list.ItemsAsMetadata()) + jsn, _ := json.Marshal(srv.DashboardItems()) fmt.Fprintf(rw, "event: captures\ndata: %s\n\n", jsn) rw.(http.Flusher).Flush() select { - case <-list.Updated(): + case <-srv.Updated(): case <-req.Context().Done(): return } @@ -76,9 +76,9 @@ func NewDashboardConnHandler(list *CaptureList) http.HandlerFunc { } // NewDashboardClearHandler clears all the captures -func NewDashboardClearHandler(list *CaptureList) http.HandlerFunc { +func NewDashboardClearHandler(srv *CaptureService) http.HandlerFunc { return func(rw http.ResponseWriter, req *http.Request) { - list.RemoveAll() + srv.RemoveAll() rw.WriteHeader(http.StatusOK) } } @@ -99,10 +99,10 @@ func NewDashboardHTMLHandler(config Config) http.HandlerFunc { } // NewDashboardRetryHandler retries a request -func NewDashboardRetryHandler(list *CaptureList, next http.HandlerFunc) http.HandlerFunc { +func NewDashboardRetryHandler(srv *CaptureService, next http.HandlerFunc) http.HandlerFunc { return func(rw http.ResponseWriter, req *http.Request) { id := req.URL.Path[strings.LastIndex(req.URL.Path, "/")+1:] - capture := list.Find(id) + capture := srv.Find(id) var reqBody []byte capture.Req.Body, reqBody = drain(capture.Req.Body) r, _ := http.NewRequest(capture.Req.Method, capture.Req.URL.String(), bytes.NewReader(reqBody)) @@ -112,17 +112,17 @@ func NewDashboardRetryHandler(list *CaptureList, next http.HandlerFunc) http.Han } // NewDashboardInfoHandler returns the full capture info -func NewDashboardInfoHandler(list *CaptureList) http.HandlerFunc { +func NewDashboardInfoHandler(srv *CaptureService) http.HandlerFunc { return func(rw http.ResponseWriter, req *http.Request) { id := req.URL.Path[strings.LastIndex(req.URL.Path, "/")+1:] - capture := list.Find(id) + capture := srv.Find(id) rw.Header().Add("Content-Type", "application/json") json.NewEncoder(rw).Encode(dump(capture)) } } -// NewPlugin loads plugin files in the current directory. They are loaded sorted by filename. -func NewPlugin(next http.HandlerFunc) http.HandlerFunc { +// NewPluginHandler loads plugin files in the current directory. They are loaded sorted by filename. +func NewPluginHandler(next http.HandlerFunc) http.HandlerFunc { ex, err := os.Executable() if err != nil { fmt.Println("error: could not get executable:", err) @@ -161,8 +161,8 @@ func NewPlugin(next http.HandlerFunc) http.HandlerFunc { return next } -// NewRecorder saves all the traffic data -func NewRecorder(list *CaptureList, next http.HandlerFunc) http.HandlerFunc { +// NewRecorderHandler saves all the traffic data +func NewRecorderHandler(srv *CaptureService, next http.HandlerFunc) http.HandlerFunc { return func(rw http.ResponseWriter, req *http.Request) { // save req body for later @@ -187,7 +187,7 @@ func NewRecorder(list *CaptureList, next http.HandlerFunc) http.HandlerFunc { // record req and res req.Body = ioutil.NopCloser(bytes.NewReader(reqBody)) res := rec.Result() - list.Insert(Capture{Req: req, Res: res, Elapsed: elapsed}) + srv.Insert(Capture{Req: req, Res: res, Elapsed: elapsed}) } }