github.com/google/martian/v3@v3.3.3/har/har_handlers.go (about) 1 // Copyright 2015 Google Inc. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package har 16 17 import ( 18 "encoding/json" 19 "net/http" 20 "net/url" 21 "strconv" 22 23 "github.com/google/martian/v3/log" 24 ) 25 26 type exportHandler struct { 27 logger *Logger 28 } 29 30 type resetHandler struct { 31 logger *Logger 32 } 33 34 // NewExportHandler returns an http.Handler for requesting HAR logs. 35 func NewExportHandler(l *Logger) http.Handler { 36 return &exportHandler{ 37 logger: l, 38 } 39 } 40 41 // NewResetHandler returns an http.Handler for clearing in-memory log entries. 42 func NewResetHandler(l *Logger) http.Handler { 43 return &resetHandler{ 44 logger: l, 45 } 46 } 47 48 // ServeHTTP writes the log in HAR format to the response body. 49 func (h *exportHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { 50 if req.Method != "GET" { 51 rw.Header().Add("Allow", "GET") 52 rw.WriteHeader(http.StatusMethodNotAllowed) 53 log.Errorf("har.ServeHTTP: method not allowed: %s", req.Method) 54 return 55 } 56 log.Debugf("exportHandler.ServeHTTP: writing HAR logs to ResponseWriter") 57 rw.Header().Set("Content-Type", "application/json; charset=utf-8") 58 59 hl := h.logger.Export() 60 json.NewEncoder(rw).Encode(hl) 61 } 62 63 // ServeHTTP resets the log, which clears its entries. 64 func (h *resetHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { 65 if !(req.Method == "POST" || req.Method == "DELETE") { 66 rw.Header().Add("Allow", "POST") 67 rw.Header().Add("Allow", "DELETE") 68 rw.WriteHeader(http.StatusMethodNotAllowed) 69 log.Errorf("har: method not allowed: %s", req.Method) 70 return 71 } 72 73 74 v, err := parseBoolQueryParam(req.URL.Query(), "return") 75 if err != nil { 76 log.Errorf("har: invalid value for return param: %s", err) 77 rw.WriteHeader(http.StatusBadRequest) 78 return 79 } 80 81 if v { 82 rw.Header().Set("Content-Type", "application/json; charset=utf-8") 83 hl := h.logger.ExportAndReset() 84 json.NewEncoder(rw).Encode(hl) 85 } else { 86 h.logger.Reset() 87 rw.WriteHeader(http.StatusNoContent) 88 } 89 90 log.Infof("resetHandler.ServeHTTP: HAR logs cleared") 91 } 92 93 func parseBoolQueryParam(params url.Values, name string) (bool, error) { 94 if params[name] == nil { 95 return false, nil 96 } 97 v, err := strconv.ParseBool(params.Get("return")) 98 if err != nil { 99 return false, err 100 } 101 return v, nil 102 }