diff --git a/handlers.go b/handlers.go index e9a6740..a7a1774 100644 --- a/handlers.go +++ b/handlers.go @@ -10,32 +10,32 @@ import ( "github.com/gorilla/schema" ) -// SearchRequest describes an incoming search request. -type SearchRequest struct { - Title string `schema:"title"` - Description string `schema:"description"` - Auth string `schema:"auth"` - HTTPS string `schema:"https"` - Cors string `schema:"cors"` - Category string `schema:"category"` -} - -// Entries contains an array of API entries, and a count representing the length of that array. -type Entries struct { - Count int `json:"count"` - Entries []Entry `json:"entries"` -} - -// Entry describes a single API reference. -type Entry struct { - API string - Description string - Auth string - HTTPS bool - Cors string - Link string - Category string -} +type ( + // SearchRequest describes an incoming search request. + SearchRequest struct { + Title string `schema:"title"` + Description string `schema:"description"` + Auth string `schema:"auth"` + HTTPS string `schema:"https"` + Cors string `schema:"cors"` + Category string `schema:"category"` + } + // Entries contains an array of API entries, and a count representing the length of that array. + Entries struct { + Count int `json:"count"` + Entries []Entry `json:"entries"` + } + // Entry describes a single API reference. + Entry struct { + API string + Description string + Auth string + HTTPS bool + Cors string + Link string + Category string + } +) // checkEntryMatches checks if the given entry matches the given request's parameters. // it returns true if the entry matches, and returns false otherwise. diff --git a/handlers_test.go b/handlers_test.go index d50caae..bb6c7b9 100644 --- a/handlers_test.go +++ b/handlers_test.go @@ -41,9 +41,7 @@ func TestHealthCheckHandler(t *testing.T) { } rr := httptest.NewRecorder() handler := healthCheckHandler() - handler.ServeHTTP(rr, req) - if status := rr.Code; status != http.StatusOK { t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK) @@ -62,9 +60,7 @@ func TestGetEntriesHandler(t *testing.T) { } rr := httptest.NewRecorder() handler := getEntriesHandler() - handler.ServeHTTP(rr, req) - if status := rr.Code; status != http.StatusOK { t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK) @@ -77,9 +73,7 @@ func TestGetEntriesWithBadMethod(t *testing.T) { } rr := httptest.NewRecorder() handler := getEntriesHandler() - handler.ServeHTTP(rr, req) - if status := rr.Code; status != http.StatusMethodNotAllowed { t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusMethodNotAllowed) diff --git a/logger.go b/logger.go index bc1580b..5e358bc 100644 --- a/logger.go +++ b/logger.go @@ -8,27 +8,34 @@ import ( "time" ) -// Options is a struct for specifying configuration parameters for the Logger middleware. -type Options struct { - // Prefix is the outputted keyword in front of the log message. Logger automatically wraps the prefix in square brackets (ie. [myApp] ) unless the `DisableAutoBrackets` is set to true. A blank value will not have brackets added. Default is blank (with no brackets). - Prefix string - // DisableAutoBrackets if set to true, will remove the prefix and square brackets. Default is false. - DisableAutoBrackets bool - // RemoteAddressHeaders is a list of header keys that Logger will look at to determine the proper remote address. Useful when using a proxy like Nginx: `[]string{"X-Forwarded-Proto"}`. Default is an empty slice, and thus will use `reqeust.RemoteAddr`. - RemoteAddressHeaders []string - // Out is the destination to which the logged data will be written too. Default is `os.Stdout`. - Out io.Writer - // OutputFlags defines the logging properties. See http://golang.org/pkg/log/#pkg-constants. To disable all flags, set this to `-1`. Defaults to log.LstdFlags (2009/01/23 01:23:23). - OutputFlags int - // IgnoredRequestURIs is a list of path values we do not want logged out. Exact match only! - IgnoredRequestURIs []string -} - -// Logger is a HTTP middleware handler that logs a request. Outputted information includes status, method, URL, remote address, size, and the time it took to process the request. -type Logger struct { - *log.Logger - opt Options -} +type ( + // Options is a struct for specifying configuration parameters for the Logger middleware. + Options struct { + // Prefix is the outputted keyword in front of the log message. Logger automatically wraps the prefix in square brackets (ie. [myApp] ) unless the `DisableAutoBrackets` is set to true. A blank value will not have brackets added. Default is blank (with no brackets). + Prefix string + // DisableAutoBrackets if set to true, will remove the prefix and square brackets. Default is false. + DisableAutoBrackets bool + // RemoteAddressHeaders is a list of header keys that Logger will look at to determine the proper remote address. Useful when using a proxy like Nginx: `[]string{"X-Forwarded-Proto"}`. Default is an empty slice, and thus will use `reqeust.RemoteAddr`. + RemoteAddressHeaders []string + // Out is the destination to which the logged data will be written too. Default is `os.Stdout`. + Out io.Writer + // OutputFlags defines the logging properties. See http://golang.org/pkg/log/#pkg-constants. To disable all flags, set this to `-1`. Defaults to log.LstdFlags (2009/01/23 01:23:23). + OutputFlags int + // IgnoredRequestURIs is a list of path values we do not want logged out. Exact match only! + IgnoredRequestURIs []string + } + // Logger is a HTTP middleware handler that logs a request. Outputted information includes status, method, URL, remote address, size, and the time it took to process the request. + Logger struct { + *log.Logger + opt Options + } + // customResponseWriter is a wrapper around golang's standard ResponseWriter to include a status code and response size + customResponseWriter struct { + http.ResponseWriter + status int + size int + } +) // NewLogger returns a reference to a configured instance of Logger func NewLogger(opts ...Options) *Logger { @@ -38,13 +45,11 @@ func NewLogger(opts ...Options) *Logger { } else { o = opts[0] } - // Determine prefix. prefix := o.Prefix if len(prefix) > 0 && o.DisableAutoBrackets == false { prefix = "[" + prefix + "] " } - // Determine output writer. var output io.Writer if o.Out != nil { @@ -53,7 +58,6 @@ func NewLogger(opts ...Options) *Logger { // Default is stdout. output = os.Stdout } - // Determine output flags. flags := log.LstdFlags if o.OutputFlags == -1 { @@ -61,7 +65,6 @@ func NewLogger(opts ...Options) *Logger { } else if o.OutputFlags != 0 { flags = o.OutputFlags } - return &Logger{ Logger: log.New(output, prefix, flags), opt: o, @@ -73,13 +76,11 @@ func (l *Logger) logFunc(rw http.ResponseWriter, r *http.Request, next http.Hand crw := newCustomResponseWriter(rw) next(crw, r) end := time.Now() - for _, ignoredURI := range l.opt.IgnoredRequestURIs { if ignoredURI == r.RequestURI { return } } - addr := r.RemoteAddr headersToCheck := []string{"X-Real-Ip", "X-Forwarded-For"} for _, headerKey := range headersToCheck { @@ -88,16 +89,9 @@ func (l *Logger) logFunc(rw http.ResponseWriter, r *http.Request, next http.Hand break } } - l.Printf("| %3d | %13v | %50s | %8d | %5s %s\n", crw.status, end.Sub(start), addr, crw.size, r.Method, r.RequestURI) } -type customResponseWriter struct { - http.ResponseWriter - status int - size int -} - func (c *customResponseWriter) WriteHeader(status int) { c.status = status c.ResponseWriter.WriteHeader(status) diff --git a/logger_test.go b/logger_test.go index 44f84d7..f36094c 100644 --- a/logger_test.go +++ b/logger_test.go @@ -16,18 +16,17 @@ var ( }) ) +func expect(t *testing.T, a interface{}, b interface{}) { + if a != b { + t.Errorf("Expected [%v] (type %v) - Got [%v] (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a)) + } +} + func TestNoConfig(t *testing.T) { res := httptest.NewRecorder() req, _ := http.NewRequest("GET", "/should/be/stdout/", nil) req.RemoteAddr = "111.222.333.444" myHandler.ServeHTTP(res, req) - expect(t, res.Code, http.StatusOK) expect(t, res.Body.String(), "bar") } - -func expect(t *testing.T, a interface{}, b interface{}) { - if a != b { - t.Errorf("Expected [%v] (type %v) - Got [%v] (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a)) - } -}