response meta

master
Jordan Orelli 8 years ago
parent c623b59b08
commit 112709f8ef

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
"sync/atomic"
"github.com/jordanorelli/dws/events" "github.com/jordanorelli/dws/events"
) )
@ -17,7 +18,11 @@ type server struct {
func (s *server) listen() { func (s *server) listen() {
addr := fmt.Sprintf("0.0.0.0:%d", s.port) addr := fmt.Sprintf("0.0.0.0:%d", s.port)
log.Printf("server listening on addr: %s\n", addr) 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) panic(err)
} }
} }
@ -28,18 +33,63 @@ func (s *server) setRoot(path string) {
} }
func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
s.out <- events.BeginRequestEvent{
Path: r.URL.Path,
}
if s.root == "" { if s.root == "" {
writeNotInitializedResponse(w) writeNotInitializedResponse(w)
return return
} }
fmt.Fprintf(w, "root: %s", s.root) fmt.Fprintf(w, "root: %s", s.root)
s.out <- events.EndRequestEvent{}
} }
func writeNotInitializedResponse(w http.ResponseWriter) { func writeNotInitializedResponse(w http.ResponseWriter) {
w.WriteHeader(500) w.WriteHeader(500)
fmt.Fprintln(w, "no root directory selected") 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)
}

@ -17,10 +17,14 @@ type SetRootEvent struct {
} }
type BeginRequestEvent struct { type BeginRequestEvent struct {
Seq int
Path string Path string
backgroundEvent backgroundEvent
} }
type EndRequestEvent struct { type EndRequestEvent struct {
Seq int
Status int
Bytes int
backgroundEvent backgroundEvent
} }

@ -3,7 +3,7 @@
@protocol EventListener @protocol EventListener
- (void) serverDidSetRoot:(NSString *)path; - (void) serverDidSetRoot:(NSString *)path;
- (void) serverDidBeginHandlingRequest:(RequestMeta *)meta; - (void) serverDidReceiveRequest:(RequestMeta *)meta;
- (void) serverDidFinishHandlingRequest; - (void) serverDidWriteResponse:(ResponseMeta *)meta;
@end @end

@ -79,12 +79,12 @@
[self.selectedDirectoryText setStringValue:path]; [self.selectedDirectoryText setStringValue:path];
} }
- (void) serverDidBeginHandlingRequest:(RequestMeta *)meta { - (void) serverDidReceiveRequest:(RequestMeta *)meta {
NSLog(@"[MainViewController] request start: %s", meta->path); NSLog(@"[MainViewController] request start: {%d %s}", meta->seq, meta->path);
} }
- (void) serverDidFinishHandlingRequest { - (void) serverDidWriteResponse:(ResponseMeta *)meta {
NSLog(@"[MainViewController] request finish"); NSLog(@"[MainViewController] request finish: {%d %d %d}", meta->seq, meta->status, meta->bytes);
} }
@end @end

@ -58,13 +58,18 @@ func (ui *cocoaUI) forwardEvent(e events.BackgroundEvent) {
defer C.free(unsafe.Pointer(cpath)) defer C.free(unsafe.Pointer(cpath))
req := &C.struct_RequestMeta{ req := &C.struct_RequestMeta{
seq: C.int(v.Seq),
path: cpath, path: cpath,
} }
C.begin_request(req) C.received_request(req)
case events.EndRequestEvent: 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),
})
} }
} }

@ -1,11 +1,14 @@
struct RequestMeta { struct RequestMeta {
int seq;
char *path; char *path;
}; };
typedef struct RequestMeta RequestMeta; typedef struct RequestMeta RequestMeta;
struct ResponseMeta { struct ResponseMeta {
int seq;
int status;
int bytes;
}; };
typedef struct ResponseMeta ResponseMeta; typedef struct ResponseMeta ResponseMeta;
@ -14,5 +17,5 @@ void initialize();
int run(); int run();
void shutdown(); void shutdown();
void set_root(char *); void set_root(char *);
void begin_request(RequestMeta *); void received_request(RequestMeta *);
void end_request(); void sent_response(ResponseMeta *);

@ -28,12 +28,12 @@ void set_root(char *path) {
[listener serverDidSetRoot:[NSString stringWithUTF8String:path]]; [listener serverDidSetRoot:[NSString stringWithUTF8String:path]];
} }
void begin_request(RequestMeta *meta) { void received_request(RequestMeta *meta) {
id listener = [[EventBridge shared] listener]; id listener = [[EventBridge shared] listener];
[listener serverDidBeginHandlingRequest:meta]; [listener serverDidReceiveRequest:meta];
} }
void end_request() { void sent_response(ResponseMeta *meta) {
id listener = [[EventBridge shared] listener]; id listener = [[EventBridge shared] listener];
[listener serverDidFinishHandlingRequest]; [listener serverDidWriteResponse:meta];
} }

Loading…
Cancel
Save