srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/ipc/ipc.go50
-rw-r--r--internal/ipc/server.go21
2 files changed, 70 insertions, 1 deletions
diff --git a/internal/ipc/ipc.go b/internal/ipc/ipc.go
index 2abce89..89a8343 100644
--- a/internal/ipc/ipc.go
+++ b/internal/ipc/ipc.go
@@ -67,11 +67,34 @@ type Request struct {
// For "set_flagged" and "delete_entry": ID identifies the history
// entry. "clear_history" needs no fields at all.
Flagged bool `json:"flagged,omitempty"`
+
+ // For "import": entries to insert directly into history - the
+ // client has already parsed/converted them (e.g. from a HAR file,
+ // see cmd/mitmux/har.go); the daemon just stores them.
+ ImportEntries []ImportEntry `json:"import_entries,omitempty"`
+}
+
+// ImportEntry is one entry to insert directly into history via
+// "import". RequestExact/ResponseExact are always false once stored:
+// an imported entry is reconstructed from whatever structured format it
+// came from (HAR, say), never the literal bytes that were on the wire
+// for the original request - the same situation an HTTP/2 capture is
+// already in.
+type ImportEntry struct {
+ Method string `json:"method"`
+ Scheme string `json:"scheme"`
+ Host string `json:"host"`
+ Path string `json:"path"`
+ StatusCode int `json:"status_code"`
+ RequestRaw []byte `json:"request_raw"`
+ ResponseRaw []byte `json:"response_raw"`
+ StartedAt time.Time `json:"started_at"`
+ Duration time.Duration `json:"duration"`
}
// Response is sent by the daemon to a client.
type Response struct {
- Type string `json:"type"` // "list", "get", "new", "repeat", "rules", "scope_rules", "intrude_result", "intrude_done", "status", "flagged", "deleted", "cleared", or "error"
+ Type string `json:"type"` // "list", "get", "new", "repeat", "rules", "scope_rules", "intrude_result", "intrude_done", "import_done", "status", "flagged", "deleted", "cleared", or "error"
Entries []store.Summary `json:"entries,omitempty"` // for "list"
Detail *EntryDetail `json:"detail,omitempty"` // for "get" and "repeat"
New *store.Summary `json:"new,omitempty"` // for "new" (subscribe push)
@@ -79,6 +102,10 @@ type Response struct {
ScopeRules []scope.Rule `json:"scope_rules,omitempty"` // for "scope_rules"
Status *StatusMsg `json:"status,omitempty"` // for "status"
+ // For "import_done": how many entries were actually inserted (a
+ // per-entry insert failure is skipped, not fatal to the batch).
+ Imported int `json:"imported,omitempty"`
+
// For "intrude_result": one completed attack request.
IntrudeResult *IntrudeResultMsg `json:"intrude_result,omitempty"`
@@ -203,6 +230,27 @@ func (c *Client) ClearHistory() error {
return nil
}
+// Import inserts entries directly into history - used to bring in
+// traffic from an external source (a HAR file, say) rather than
+// something mitmux itself captured. Returns how many were actually
+// inserted; a per-entry insert failure is skipped rather than aborting
+// the whole batch.
+func (c *Client) Import(entries []ImportEntry) (int, error) {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ if err := c.enc.Encode(Request{Type: "import", ImportEntries: entries}); err != nil {
+ return 0, err
+ }
+ var resp Response
+ if err := c.dec.Decode(&resp); err != nil {
+ return 0, err
+ }
+ if resp.Type == "error" {
+ return 0, errors.New(resp.Error)
+ }
+ return resp.Imported, nil
+}
+
// Status returns basic daemon info for a status bar.
func (c *Client) Status() (*StatusMsg, error) {
c.mu.Lock()
diff --git a/internal/ipc/server.go b/internal/ipc/server.go
index 303fdef..c83254e 100644
--- a/internal/ipc/server.go
+++ b/internal/ipc/server.go
@@ -230,6 +230,27 @@ func (s *Server) handleConn(conn net.Conn) {
}
enc.Encode(Response{Type: "cleared"})
+ case "import":
+ imported := 0
+ for _, ie := range req.ImportEntries {
+ e := &store.Entry{
+ StartedAt: ie.StartedAt,
+ Duration: ie.Duration,
+ Method: ie.Method,
+ Scheme: ie.Scheme,
+ Host: ie.Host,
+ Path: ie.Path,
+ StatusCode: ie.StatusCode,
+ RequestRaw: ie.RequestRaw,
+ ResponseRaw: ie.ResponseRaw,
+ Source: "import",
+ }
+ if _, err := s.db.Insert(e); err == nil {
+ imported++
+ }
+ }
+ enc.Encode(Response{Type: "import_done", Imported: imported})
+
case "rules_list":
rs, err := s.db.ListRules()
if err != nil {