github.com/DamienFontaine/lunarc@v0.0.0-20190122154304-2e7332a51f55/web/handlers.go (about) 1 // Copyright (c) - Damien Fontaine <damien.fontaine@lineolia.net> 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, either version 3 of the License, or 6 // (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU General Public License for more details. 12 // 13 // You should have received a copy of the GNU General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/> 15 16 package web 17 18 import ( 19 "bufio" 20 "errors" 21 "net" 22 "net/http" 23 "time" 24 25 "github.com/Sirupsen/logrus" 26 ) 27 28 //Logging logs http requests 29 func Logging(next http.Handler, log *logrus.Logger) http.Handler { 30 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 31 srw := StatusResponseWriter{w, 0, 0} 32 start := time.Now() 33 next.ServeHTTP(&srw, r) 34 end := time.Now() 35 latency := end.Sub(start) 36 37 log.WithField("client", r.RemoteAddr).WithField("latency", latency).WithField("length", srw.Length()).WithField("code", srw.Status()).Printf("%s %s %s", r.Method, r.URL, r.Proto) 38 }) 39 } 40 41 //SingleFile returns a handler 42 func SingleFile(filename string) http.Handler { 43 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 44 http.ServeFile(w, r, filename) 45 }) 46 } 47 48 // StatusResponseWriter returns status code 49 type StatusResponseWriter struct { 50 http.ResponseWriter 51 status int 52 length int 53 } 54 55 // Status return status code 56 func (w *StatusResponseWriter) Status() int { 57 return w.status 58 } 59 60 // Length return response size 61 func (w *StatusResponseWriter) Length() int { 62 return w.length 63 } 64 65 // Header Satisfy the http.ResponseWriter interface 66 func (w *StatusResponseWriter) Header() http.Header { 67 return w.ResponseWriter.Header() 68 } 69 70 // Write Satisfy the http.ResponseWriter interface 71 func (w *StatusResponseWriter) Write(data []byte) (int, error) { 72 w.length = len(data) 73 return w.ResponseWriter.Write(data) 74 } 75 76 //Hijack Satisfy the http.ResponseWriter interface 77 func (w *StatusResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { 78 if hj, ok := w.ResponseWriter.(http.Hijacker); ok { 79 return hj.Hijack() 80 } 81 return nil, nil, errors.New("Not a Hijacker") 82 } 83 84 // WriteHeader writes status code 85 func (w *StatusResponseWriter) WriteHeader(statusCode int) { 86 w.status = statusCode 87 w.ResponseWriter.WriteHeader(statusCode) 88 }