From 112709f8ef6079f296e890eca5c979c461363a2f Mon Sep 17 00:00:00 2001 From: Jordan Orelli Date: Sat, 17 Jun 2017 23:43:09 -0500 Subject: [PATCH] response meta --- bg/server.go | 60 ++++++++++++++++++++++++++++++++++---- events/background_event.go | 4 +++ ui/EventListener.h | 4 +-- ui/MainViewController.m | 8 ++--- ui/ui_darwin.go | 9 ++++-- ui/ui_darwin.h | 9 ++++-- ui/ui_darwin.m | 8 ++--- 7 files changed, 82 insertions(+), 20 deletions(-) diff --git a/bg/server.go b/bg/server.go index 9cf1af1..5c0819c 100644 --- a/bg/server.go +++ b/bg/server.go @@ -4,6 +4,7 @@ import ( "fmt" "log" "net/http" + "sync/atomic" "github.com/jordanorelli/dws/events" ) @@ -17,7 +18,11 @@ type server struct { func (s *server) listen() { addr := fmt.Sprintf("0.0.0.0:%d", s.port) log.Printf("server listening on addr: %s\n", addr) - if err := http.ListenAndServe(addr, s); err != nil { + h := &eventEmittingHandler{ + wrapped: s, + out: s.out, + } + if err := http.ListenAndServe(addr, h); err != nil { panic(err) } } @@ -28,18 +33,63 @@ func (s *server) setRoot(path string) { } func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) { - s.out <- events.BeginRequestEvent{ - Path: r.URL.Path, - } if s.root == "" { writeNotInitializedResponse(w) return } fmt.Fprintf(w, "root: %s", s.root) - s.out <- events.EndRequestEvent{} } func writeNotInitializedResponse(w http.ResponseWriter) { w.WriteHeader(500) fmt.Fprintln(w, "no root directory selected") } + +// trackginWriter is an http.ResponseWriter that tracks the number of bytes +// sent and the status sent +type trackingWriter struct { + http.ResponseWriter + status int // last http status written + wrote int // total number of bytes written +} + +func (t *trackingWriter) WriteHeader(status int) { + t.ResponseWriter.WriteHeader(status) + t.status = status +} + +func (t *trackingWriter) Write(b []byte) (int, error) { + n, err := t.ResponseWriter.Write(b) + if t.status == 0 { + t.status = 200 + } + t.wrote += n + return n, err +} + +// eventEmittingHandler is an http.Handler that emits events on an event +// channel to report on requests and responses. +type eventEmittingHandler struct { + wrapped http.Handler + out chan events.BackgroundEvent + count uint32 +} + +func (h *eventEmittingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + id := int(h.nextCount()) + h.out <- events.BeginRequestEvent{ + Seq: id, + Path: r.URL.Path, + } + tw := &trackingWriter{ResponseWriter: w} + h.wrapped.ServeHTTP(tw, r) + h.out <- events.EndRequestEvent{ + Seq: id, + Status: tw.status, + Bytes: tw.wrote, + } +} + +func (h *eventEmittingHandler) nextCount() uint32 { + return atomic.AddUint32(&h.count, 1) +} diff --git a/events/background_event.go b/events/background_event.go index 3d2997e..c59f89b 100644 --- a/events/background_event.go +++ b/events/background_event.go @@ -17,10 +17,14 @@ type SetRootEvent struct { } type BeginRequestEvent struct { + Seq int Path string backgroundEvent } type EndRequestEvent struct { + Seq int + Status int + Bytes int backgroundEvent } diff --git a/ui/EventListener.h b/ui/EventListener.h index 8cfa1dd..10e377f 100644 --- a/ui/EventListener.h +++ b/ui/EventListener.h @@ -3,7 +3,7 @@ @protocol EventListener - (void) serverDidSetRoot:(NSString *)path; -- (void) serverDidBeginHandlingRequest:(RequestMeta *)meta; -- (void) serverDidFinishHandlingRequest; +- (void) serverDidReceiveRequest:(RequestMeta *)meta; +- (void) serverDidWriteResponse:(ResponseMeta *)meta; @end diff --git a/ui/MainViewController.m b/ui/MainViewController.m index f95ef8e..30263cb 100644 --- a/ui/MainViewController.m +++ b/ui/MainViewController.m @@ -79,12 +79,12 @@ [self.selectedDirectoryText setStringValue:path]; } -- (void) serverDidBeginHandlingRequest:(RequestMeta *)meta { - NSLog(@"[MainViewController] request start: %s", meta->path); +- (void) serverDidReceiveRequest:(RequestMeta *)meta { + NSLog(@"[MainViewController] request start: {%d %s}", meta->seq, meta->path); } -- (void) serverDidFinishHandlingRequest { - NSLog(@"[MainViewController] request finish"); +- (void) serverDidWriteResponse:(ResponseMeta *)meta { + NSLog(@"[MainViewController] request finish: {%d %d %d}", meta->seq, meta->status, meta->bytes); } @end diff --git a/ui/ui_darwin.go b/ui/ui_darwin.go index 077d0bc..c3af25d 100644 --- a/ui/ui_darwin.go +++ b/ui/ui_darwin.go @@ -58,13 +58,18 @@ func (ui *cocoaUI) forwardEvent(e events.BackgroundEvent) { defer C.free(unsafe.Pointer(cpath)) req := &C.struct_RequestMeta{ + seq: C.int(v.Seq), path: cpath, } - C.begin_request(req) + C.received_request(req) case events.EndRequestEvent: - C.end_request() + C.sent_response(&C.struct_ResponseMeta{ + seq: C.int(v.Seq), + status: C.int(v.Status), + bytes: C.int(v.Bytes), + }) } } diff --git a/ui/ui_darwin.h b/ui/ui_darwin.h index 05a20ff..0f93d8f 100644 --- a/ui/ui_darwin.h +++ b/ui/ui_darwin.h @@ -1,11 +1,14 @@ struct RequestMeta { + int seq; char *path; }; typedef struct RequestMeta RequestMeta; struct ResponseMeta { - + int seq; + int status; + int bytes; }; typedef struct ResponseMeta ResponseMeta; @@ -14,5 +17,5 @@ void initialize(); int run(); void shutdown(); void set_root(char *); -void begin_request(RequestMeta *); -void end_request(); +void received_request(RequestMeta *); +void sent_response(ResponseMeta *); diff --git a/ui/ui_darwin.m b/ui/ui_darwin.m index bf38b04..f4ab8aa 100644 --- a/ui/ui_darwin.m +++ b/ui/ui_darwin.m @@ -28,12 +28,12 @@ void set_root(char *path) { [listener serverDidSetRoot:[NSString stringWithUTF8String:path]]; } -void begin_request(RequestMeta *meta) { +void received_request(RequestMeta *meta) { id listener = [[EventBridge shared] listener]; - [listener serverDidBeginHandlingRequest:meta]; + [listener serverDidReceiveRequest:meta]; } -void end_request() { +void sent_response(ResponseMeta *meta) { id listener = [[EventBridge shared] listener]; - [listener serverDidFinishHandlingRequest]; + [listener serverDidWriteResponse:meta]; }