You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
2.7 KiB

  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. package har
  15. import (
  16. "encoding/json"
  17. "net/http"
  18. "net/url"
  19. "strconv"
  20. "github.com/google/martian/log"
  21. )
  22. type exportHandler struct {
  23. logger *Logger
  24. }
  25. type resetHandler struct {
  26. logger *Logger
  27. }
  28. // NewExportHandler returns an http.Handler for requesting HAR logs.
  29. func NewExportHandler(l *Logger) http.Handler {
  30. return &exportHandler{
  31. logger: l,
  32. }
  33. }
  34. // NewResetHandler returns an http.Handler for clearing in-memory log entries.
  35. func NewResetHandler(l *Logger) http.Handler {
  36. return &resetHandler{
  37. logger: l,
  38. }
  39. }
  40. // ServeHTTP writes the log in HAR format to the response body.
  41. func (h *exportHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
  42. if req.Method != "GET" {
  43. rw.Header().Add("Allow", "GET")
  44. rw.WriteHeader(http.StatusMethodNotAllowed)
  45. log.Errorf("har.ServeHTTP: method not allowed: %s", req.Method)
  46. return
  47. }
  48. log.Debugf("exportHandler.ServeHTTP: writing HAR logs to ResponseWriter")
  49. rw.Header().Set("Content-Type", "application/json; charset=utf-8")
  50. hl := h.logger.Export()
  51. json.NewEncoder(rw).Encode(hl)
  52. }
  53. // ServeHTTP resets the log, which clears its entries.
  54. func (h *resetHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
  55. if !(req.Method == "POST" || req.Method == "DELETE") {
  56. rw.Header().Add("Allow", "POST")
  57. rw.Header().Add("Allow", "DELETE")
  58. rw.WriteHeader(http.StatusMethodNotAllowed)
  59. log.Errorf("har: method not allowed: %s", req.Method)
  60. return
  61. }
  62. v, err := parseBoolQueryParam(req.URL.Query(), "return")
  63. if err != nil {
  64. log.Errorf("har: invalid value for return param: %s", err)
  65. rw.WriteHeader(http.StatusBadRequest)
  66. return
  67. }
  68. if v {
  69. rw.Header().Set("Content-Type", "application/json; charset=utf-8")
  70. hl := h.logger.ExportAndReset()
  71. json.NewEncoder(rw).Encode(hl)
  72. } else {
  73. h.logger.Reset()
  74. rw.WriteHeader(http.StatusNoContent)
  75. }
  76. log.Infof("resetHandler.ServeHTTP: HAR logs cleared")
  77. }
  78. func parseBoolQueryParam(params url.Values, name string) (bool, error) {
  79. if params[name] == nil {
  80. return false, nil
  81. }
  82. v, err := strconv.ParseBool(params.Get("return"))
  83. if err != nil {
  84. return false, err
  85. }
  86. return v, nil
  87. }