HTTP Archive

/app/controller/clib/har.go (4.4 KB)

  1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package clib

import (
"fmt"
"io"
"net/http"
"strings"

"github.com/pkg/errors"

"{{{ .Package }}}/app"
"{{{ .Package }}}/app/controller"
"{{{ .Package }}}/app/controller/cutil"
"{{{ .Package }}}/app/lib/har"
"{{{ .Package }}}/app/util"
"{{{ .Package }}}/views/vhar"
"{{{ .Package }}}/views/vpage"
)

func HarList(w http.ResponseWriter, r *http.Request) {
controller.Act("har.list", w, r, func(as *app.State, ps *cutil.PageState) (string, error) {
ret := as.Services.Har.List(ps.Logger)
ps.SetTitleAndData("Archives", ret)
return controller.Render(r, as, &vhar.List{Hars: ret}, ps, "har")
})
}

func HarDetail(w http.ResponseWriter, r *http.Request) {
controller.Act("har.detail", w, r, func(as *app.State, ps *cutil.PageState) (string, error) {
key, err := cutil.PathString(r, "key", true)
if err != nil {
return "", err
}
ret, err := as.Services.Har.Load(key)
if err != nil {
return "", err
}
ps.SetTitleAndData("Archive ["+key+"]", ret)
return controller.Render(r, as, &vhar.Detail{Har: ret}, ps, "har", ret.Key)
})
}

func HarDelete(w http.ResponseWriter, r *http.Request) {
controller.Act("har.delete", w, r, func(as *app.State, ps *cutil.PageState) (string, error) {
key, err := cutil.PathString(r, "key", true)
if err != nil {
return "", err
}
err = as.Services.Har.Delete(key, ps.Logger)
if err != nil {
return "", err
}
return controller.FlashAndRedir(true, "Archive deleted", "/har", ps)
})
}

func HarTrim(w http.ResponseWriter, r *http.Request) {
controller.Act("har.trim", w, r, func(as *app.State, ps *cutil.PageState) (string, error) {
key, err := cutil.PathString(r, "key", true)
if err != nil {
return "", err
}
h, err := as.Services.Har.Load(key)
if err != nil {
return "", err
}
trimArgs := util.FieldDescs{
{Key: "url", Title: "URL", Description: "matches against the URL (add \"*\" on either side to match wildcards)", Type: "string"},
{Key: "mime", Title: "MIME", Description: "matches against the MIME type of the response", Type: "string", Choices: []string{"application/json"}},
}
results := util.FieldDescsCollect(r, trimArgs)
if results.HasMissing() {
url := fmt.Sprintf("%s/trim", h.WebPath())
ps.Data = results
return controller.Render(r, as, &vpage.Args{URL: url, Directions: "Select the requests to trim", Results: results}, ps, "har", h.Key, "Trim")
}
originalCount := len(h.Entries)
h.Entries, err = h.Entries.Find(&har.Selector{URL: results.Values.GetStringOpt("url"), Mime: results.Values.GetStringOpt("mime")})
if err != nil {
return "", err
}
newCount := len(h.Entries)
if newCount == originalCount {
return controller.FlashAndRedir(true, "no changes needed", h.WebPath(), ps)
}
err = as.Services.Har.Save(h)
if err != nil {
return "", err
}
msg := fmt.Sprintf("Trimmed [%d] entries from archive", originalCount-newCount)
return controller.FlashAndRedir(true, msg, h.WebPath(), ps)
})
}

func HarUpload(w http.ResponseWriter, r *http.Request) {
controller.Act("har.upload", w, r, func(as *app.State, ps *cutil.PageState) (string, error) {
if err := r.ParseMultipartForm(cutil.MaxBodySize); err != nil {
return "", err
}
mpfrm := r.MultipartForm
name := util.StringJoin(mpfrm.Value["n"], "")
fileHeaders, ok := mpfrm.File["f"]
if !ok {
return "", errors.New("no file uploaded")
}
if len(fileHeaders) != 1 {
return "", errors.New("invalid file uploads")
}
fileHeader := fileHeaders[0]
file, err := fileHeader.Open()
if err != nil {
return "", err
}
if name == "" {
name = fileHeader.Filename
if !strings.HasSuffix(name, har.Ext) {
name += har.Ext
}
}

ps.Logger.Infof("Uploaded File: %+v\n", fileHeader.Filename)
ps.Logger.Infof("File Size: %+v\n", fileHeader.Size)
ps.Logger.Infof("MIME Header: %+v\n", fileHeader.Header)

defer func() { _ = file.Close() }()
fileBytes, err := io.ReadAll(file)
if err != nil {
return "", err
}
ret := &har.Wrapper{}
err = util.FromJSON(fileBytes, ret)
if err != nil {
return "", errors.Wrapf(err, "error decoding file [%s]", name)
}
ret.Log.Key = name
err = as.Services.Har.Save(ret.Log)
if err != nil {
return "", err
}
msg := fmt.Sprintf("Created [%s] (%s)", name, util.ByteSizeSI(fileHeader.Size))
redir := "/har/" + name
return controller.FlashAndRedir(true, msg, redir, ps)
})
}